import Foundation
import PathKit

public enum Assets {

    public enum swifttemplate {
        public static let allTypes: AssetFile = Files.allTypes
        public static let mock: AssetFile = Files.mock
        public static let prototype: AssetFile = Files.prototype
    }

    public static var mockfileTemplate: String { return """
        # Mockfile is a SwiftyMocky YAML configuration file
        sourceryCommand: null
        unit.tests.mock:    # Name of your mock
          sources:
            include:        # All swift files here would be scanned for AutoMockable types
                - ./MyApp
            exclude: []     # You can exclude files as well
          output:           # Generated mock file location and name
            ./MyAppUnitTests/Mocks/Mock.generated.swift
          targets:          # Specify XCodeproj targets for your mock. Used for linting
            - MyAppUnitTests
          testable: []      # Specify  list of imported/@testable modules referenced in mock
          import: []        # You can use 'swiftymocky autoimport' to update it automatically
        """
    }
}

public protocol AssetFile {

    var name: String { get }
    var data: Data { get }

    func write(to path: Path) throws
}

private struct File: AssetFile {

    let name: String
    let contents: String
    var data: Data { return Data(base64Encoded: contents) ?? Data() }

    func write(to path: Path) throws {
        try path.write(data)
    }
}

private enum Files {
    static let allTypes = File(
        name: "AllTypes.swifttemplate",
        contents: "dHlwZXM6CjwlXyB2YXIgYWxsID0gdHlwZXMuYWxsCiAgICBhbGwgKz0gdHlwZXMucHJvdG9jb2xzLm1hcCB7ICQwIH0KICAgIGFsbCArPSB0eXBlcy5wcm90b2NvbENvbXBvc2l0aW9ucy5tYXAgeyAkMCB9IC0lPgo8JV8gZm9yIHR5cGUgaW4gYWxsIHsgLSU+PCVfIC0lPgogIDwlXyBsZXQgYXV0b01vY2thYmxlOiBCb29sID0gdHlwZS5pbmhlcml0ZWRUeXBlcy5jb250YWlucygiQXV0b01vY2thYmxlIikgfHwgdHlwZS5hbm5vdGF0aW9uc1siQXV0b01vY2thYmxlIl0gIT0gbmlsIC0lPgogIDwlXyBpZiBhdXRvTW9ja2FibGUgeyAtJT4KICAgIC0gPCU9IHR5cGUubmFtZSAlPgogIDwlXyB9IC0lPgo8JV8gfSAtJT4K"
    )
    static let mock = File(
        name: "Mock.swifttemplate",
        contents: "PCVfCmxldCBtb2NrVHlwZU5hbWUgPSAiTW9jayIKZnVuYyBzd2lmdExpbnRSdWxlcyhfIGFyZ3VtZW50czogW1N0cmluZzogQW55XSkgLT4gW1N0cmluZ10gewogICAgcmV0dXJuIHN0cmluZ0FycmF5KGZyb21Bcmd1bWVudHM6IGFyZ3VtZW50cywgZm9yS2V5OiAiZXhjbHVkZWRTd2lmdExpbnRSdWxlcyIpLm1hcCB7IHJ1bGUgaW4KICAgICAgICByZXR1cm4gIi8vc3dpZnRsaW50OmRpc2FibGUgXChydWxlKSIKICAgIH0KfQoKZnVuYyBwcm9qZWN0SW1wb3J0cyhfIGFyZ3VtZW50czogW1N0cmluZzogQW55XSkgLT4gW1N0cmluZ10gewogICAgcmV0dXJuIGltcG9ydHMoYXJndW1lbnRzKSArIHRlc3RhYmxlSW1wb3J0cyhhcmd1bWVudHMpCn0KCmZ1bmMgaW1wb3J0cyhfIGFyZ3VtZW50czogW1N0cmluZzogQW55XSkgLT4gW1N0cmluZ10gewogICAgcmV0dXJuIHN0cmluZ0FycmF5KGZyb21Bcmd1bWVudHM6IGFyZ3VtZW50cywgZm9yS2V5OiAiaW1wb3J0IikKICAgICAgICAubWFwIHsgcmV0dXJuICJpbXBvcnQgXCgkMCkiIH0KfQoKZnVuYyB0ZXN0YWJsZUltcG9ydHMoXyBhcmd1bWVudHM6IFtTdHJpbmc6IEFueV0pIC0+IFtTdHJpbmddIHsKICAgIHJldHVybiBzdHJpbmdBcnJheShmcm9tQXJndW1lbnRzOiBhcmd1bWVudHMsIGZvcktleTogInRlc3RhYmxlIikKICAgICAgICAubWFwIHsgcmV0dXJuICJAdGVzdGFibGUgaW1wb3J0IFwoJDApIiB9Cn0KCi8vLyBbSW50ZXJuYWxdIEdldCB2YWx1ZSBmcm9tIGRpY3Rpb25hcnkKLy8vIC0gUGFyYW1ldGVyczoKLy8vICAgLSBmcm9tQXJndW1lbnRzOiBkaWN0aW9uYXJ5Ci8vLyAgIC0gZm9yS2V5OiBkaWN0aW9uYXJ5IGtleQovLy8gLSBSZXR1cm5zOiBhcnJheSBvZiBzdHJpbmdzLCBpZiBrZXkgbm90IGZvdW5kLCByZXR1cm5zIGVtcHR5IGFycmF5LgovLy8gLSBOb3RlOiBJZiBzb3VyY2VyeSBhcmd1bWVudHMgY29udGFpbnRzIG9ubHkgb25lIGVsZW1lbnQsIHRoZW4gc2luZ2xlIHZhbHVlIGlzIHN0b3JlZCwgb3RoZXJ3aXNlIGFycmF5IG9mIGVsZW1lbnRzLiBUaGlzIG1ldGhvZCBhbHdheXMgZ2V0cyBhcnJheSBvZiBlbGVtZW50cy4KZnVuYyBzdHJpbmdBcnJheShmcm9tQXJndW1lbnRzIGFyZ3VtZW50czogW1N0cmluZzogQW55XSwgZm9yS2V5IGtleTogU3RyaW5nKSAtPiBbU3RyaW5nXSB7CgogICAgaWYgbGV0IGFyZ3VtZW50ID0gYXJndW1lbnRzW2tleV0gYXM/IFN0cmluZyB7CiAgICAgICAgcmV0dXJuIFthcmd1bWVudF0KICAgIH0gZWxzZSBpZiBsZXQgbWFueUFyZ3VtZW50cyA9IGFyZ3VtZW50c1trZXldIGFzPyBbU3RyaW5nXSB7CiAgICAgICAgcmV0dXJuIG1hbnlBcmd1bWVudHMKICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIFtdCiAgICB9Cn0KXyU+Ci8vIEdlbmVyYXRlZCB3aXRoIFN3aWZ0eU1vY2t5IDQuMi4wCi8vIFJlcXVpcmVkIFNvdXJjZXJ5OiAxLjguMAoKPCVfIGZvciBydWxlIGluIHN3aWZ0TGludFJ1bGVzKGFyZ3VtZW50KSB7IC0lPgogICAgPCVfICU+PCU9IHJ1bGUgJT4KPCVfIH0gLSU+CgppbXBvcnQgU3dpZnR5TW9ja3kKaW1wb3J0IFhDVGVzdAo8JSMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gSU1QT1JUUyAtJT48JV8gLSU+CiAgICA8JV8gZm9yIHByb2plY3RJbXBvcnQgaW4gcHJvamVjdEltcG9ydHMoYXJndW1lbnQpIHsgLSU+CiAgICAgICAgPCVfICU+PCU9IHByb2plY3RJbXBvcnQgJT4KICAgIDwlXyB9IC0lPgogICAgPCUjID09PT09PT09PT09PT09PT09PT09PT09PT09PT0gSU1QT1JUUyBJbkFQUCAoYWdncmVnYXRlZCBhcmd1bWVudCkgLSU+PCVfIC0lPgogICAgPCVfIGlmIGxldCBzd2lmdHlNb2NreUFyZ3MgPSBhcmd1bWVudFsic3dpZnR5TW9ja3kiXSBhcz8gW1N0cmluZzogQW55XSB7IC0lPgogICAgICAgIDwlXyBmb3IgcHJvamVjdEltcG9ydCBpbiBwcm9qZWN0SW1wb3J0cyhzd2lmdHlNb2NreUFyZ3MpIHsgLSU+CiAgICAgICAgICAgIDwlXyAlPjwlPSBwcm9qZWN0SW1wb3J0ICU+CiAgICAgICAgPCVfIH0gLSU+CiAgICA8JV8gfSAtJT4KPCVfCmNsYXNzIEN1cnJlbnQgewogICAgc3RhdGljIHZhciBzZWxmVHlwZTogU3RyaW5nID0gIlNlbGYiCiAgICBzdGF0aWMgdmFyIGFjY2Vzc01vZGlmaWVyOiBTdHJpbmcgPSAib3BlbiIKfQovLyBDb2xsaXNpb24gbWFuYWdlbWVudApmdW5jIGFyZVRoZXJlQ29sbGlzaW9ucyhiZXR3ZWVuIG1ldGhvZHM6IFtNZXRob2RXcmFwcGVyXSkgLT4gQm9vbCB7CiAgICBsZXQgZ2l2ZW5TZXQgPSBTZXQ8U3RyaW5nPihtZXRob2RzLm1hcCh7ICQwLmdpdmVuQ29uc3RydWN0b3JOYW1lKHByZWZpeDogIiIpIH0pKQogICAgZ3VhcmQgZ2l2ZW5TZXQuY291bnQgPT0gbWV0aG9kcy5jb3VudCBlbHNlIHsgcmV0dXJuIHRydWUgfSAvLyB0aGVyZSB3b3VsZCBiZSBjb25mbGljdHMgaW4gR2l2ZW4KICAgIGxldCB2ZXJpZnlTZXQgPSBTZXQ8U3RyaW5nPihtZXRob2RzLm1hcCh7ICQwLnZlcmlmaWNhdGlvblByb3h5Q29uc3RydWN0b3JOYW1lKHByZWZpeDogIiIpIH0pKQogICAgZ3VhcmQgdmVyaWZ5U2V0LmNvdW50ID09IG1ldGhvZHMuY291bnQgZWxzZSB7IHJldHVybiB0cnVlIH0gLy8gdGhlcmUgd291bGQgYmUgY29uZmxpY3RzIGluIFZlcmlmeQogICAgcmV0dXJuIGZhbHNlCn0KCi8vIGhlcmxwZXJzCmZ1bmMgdW5pcXVlcyhtZXRob2RzOiBbU291cmNlcnlSdW50aW1lLk1ldGhvZF0pIC0+IFtTb3VyY2VyeVJ1bnRpbWUuTWV0aG9kXSB7CiAgICBmdW5jIHJldHVyblR5cGVTdHJpcHBlZChfIG1ldGhvZDogU291cmNlcnlSdW50aW1lLk1ldGhvZCkgLT4gU3RyaW5nIHsKICAgICAgICBsZXQgcmV0dXJuVHlwZVJhdyA9ICJcKG1ldGhvZC5yZXR1cm5UeXBlTmFtZSkiCiAgICAgICAgdmFyIHN0cmlwcGVkOiBTdHJpbmcgPSB7CiAgICAgICAgICAgIGd1YXJkIGxldCByYW5nZSA9IHJldHVyblR5cGVSYXcucmFuZ2Uob2Y6ICJ3aGVyZSIpIGVsc2UgeyByZXR1cm4gcmV0dXJuVHlwZVJhdyB9CiAgICAgICAgICAgIHZhciBzdHJpcHBlZCA9IHJldHVyblR5cGVSYXcKICAgICAgICAgICAgc3RyaXBwZWQucmVtb3ZlU3VicmFuZ2UoKHJhbmdlLmxvd2VyQm91bmQpLi4uKQogICAgICAgICAgICByZXR1cm4gc3RyaXBwZWQKICAgICAgICB9KCkKICAgICAgICBzdHJpcHBlZCA9IHN0cmlwcGVkLnRyaW1taW5nQ2hhcmFjdGVycyhpbjogQ2hhcmFjdGVyU2V0KGNoYXJhY3RlcnNJbjogIiAiKSkKICAgICAgICByZXR1cm4gc3RyaXBwZWQKICAgIH0KCiAgICBmdW5jIGFyZVNhbWVQYXJhbXMoXyBwMTogU291cmNlcnlSdW50aW1lLk1ldGhvZFBhcmFtZXRlciwgXyBwMjogU291cmNlcnlSdW50aW1lLk1ldGhvZFBhcmFtZXRlcikgLT4gQm9vbCB7CiAgICAgICAgZ3VhcmQgcDEuYXJndW1lbnRMYWJlbCA9PSBwMi5hcmd1bWVudExhYmVsIGVsc2UgeyByZXR1cm4gZmFsc2UgfQogICAgICAgIGd1YXJkIHAxLm5hbWUgPT0gcDIubmFtZSBlbHNlIHsgcmV0dXJuIGZhbHNlIH0KICAgICAgICBndWFyZCBwMS5hcmd1bWVudExhYmVsID09IHAyLmFyZ3VtZW50TGFiZWwgZWxzZSB7IHJldHVybiBmYWxzZSB9CiAgICAgICAgZ3VhcmQgcDEudHlwZU5hbWUubmFtZSA9PSBwMi50eXBlTmFtZS5uYW1lIGVsc2UgeyByZXR1cm4gZmFsc2UgfQogICAgICAgIGd1YXJkIHAxLmFjdHVhbFR5cGVOYW1lPy5uYW1lID09IHAyLmFjdHVhbFR5cGVOYW1lPy5uYW1lIGVsc2UgeyByZXR1cm4gZmFsc2UgfQogICAgICAgIHJldHVybiB0cnVlCiAgICB9CgogICAgZnVuYyBhcmVTYW1lTWV0aG9kcyhfIG0xOiBTb3VyY2VyeVJ1bnRpbWUuTWV0aG9kLCBfIG0yOiBTb3VyY2VyeVJ1bnRpbWUuTWV0aG9kKSAtPiBCb29sIHsKICAgICAgICBndWFyZCBtMS5uYW1lICE9IG0yLm5hbWUgZWxzZSB7IHJldHVybiBtMS5yZXR1cm5UeXBlTmFtZSA9PSBtMi5yZXR1cm5UeXBlTmFtZSB9CiAgICAgICAgZ3VhcmQgbTEuc2VsZWN0b3JOYW1lID09IG0yLnNlbGVjdG9yTmFtZSBlbHNlIHsgcmV0dXJuIGZhbHNlIH0KICAgICAgICBndWFyZCBtMS5wYXJhbWV0ZXJzLmNvdW50ID09IG0yLnBhcmFtZXRlcnMuY291bnQgZWxzZSB7IHJldHVybiBmYWxzZSB9CgogICAgICAgIGxldCBwMSA9IG0xLnBhcmFtZXRlcnMKICAgICAgICBsZXQgcDIgPSBtMi5wYXJhbWV0ZXJzCgogICAgICAgIGZvciBpIGluIDAuLjxwMS5jb3VudCB7CiAgICAgICAgICAgIGlmICFhcmVTYW1lUGFyYW1zKHAxW2ldLHAyW2ldKSB7IHJldHVybiBmYWxzZSB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbTEucmV0dXJuVHlwZU5hbWUgPT0gbTIucmV0dXJuVHlwZU5hbWUKICAgIH0KCiAgICByZXR1cm4gbWV0aG9kcy5yZWR1Y2UoW10sIHsgKHJlc3VsdCwgZWxlbWVudCkgLT4gW1NvdXJjZXJ5UnVudGltZS5NZXRob2RdIGluCiAgICAgICAgZ3VhcmQgIXJlc3VsdC5jb250YWlucyh3aGVyZTogeyBhcmVTYW1lTWV0aG9kcygkMCxlbGVtZW50KSB9KSBlbHNlIHsgcmV0dXJuIHJlc3VsdCB9CiAgICAgICAgcmV0dXJuIHJlc3VsdCArIFtlbGVtZW50XQogICAgfSkKfQoKZnVuYyB1bmlxdWVzV2l0aG91dEdlbmVyaWNDb25zdHJhaW50cyhtZXRob2RzOiBbU291cmNlcnlSdW50aW1lLk1ldGhvZF0pIC0+IFtTb3VyY2VyeVJ1bnRpbWUuTWV0aG9kXSB7CiAgICBmdW5jIHJldHVyblR5cGVTdHJpcHBlZChfIG1ldGhvZDogU291cmNlcnlSdW50aW1lLk1ldGhvZCkgLT4gU3RyaW5nIHsKICAgICAgICBsZXQgcmV0dXJuVHlwZVJhdyA9ICJcKG1ldGhvZC5yZXR1cm5UeXBlTmFtZSkiCiAgICAgICAgdmFyIHN0cmlwcGVkOiBTdHJpbmcgPSB7CiAgICAgICAgICAgIGd1YXJkIGxldCByYW5nZSA9IHJldHVyblR5cGVSYXcucmFuZ2Uob2Y6ICJ3aGVyZSIpIGVsc2UgeyByZXR1cm4gcmV0dXJuVHlwZVJhdyB9CiAgICAgICAgICAgIHZhciBzdHJpcHBlZCA9IHJldHVyblR5cGVSYXcKICAgICAgICAgICAgc3RyaXBwZWQucmVtb3ZlU3VicmFuZ2UoKHJhbmdlLmxvd2VyQm91bmQpLi4uKQogICAgICAgICAgICByZXR1cm4gc3RyaXBwZWQKICAgICAgICB9KCkKICAgICAgICBzdHJpcHBlZCA9IHN0cmlwcGVkLnRyaW1taW5nQ2hhcmFjdGVycyhpbjogQ2hhcmFjdGVyU2V0KGNoYXJhY3RlcnNJbjogIiAiKSkKICAgICAgICByZXR1cm4gc3RyaXBwZWQKICAgIH0KCiAgICBmdW5jIGFyZVNhbWVQYXJhbXMoXyBwMTogU291cmNlcnlSdW50aW1lLk1ldGhvZFBhcmFtZXRlciwgXyBwMjogU291cmNlcnlSdW50aW1lLk1ldGhvZFBhcmFtZXRlcikgLT4gQm9vbCB7CiAgICAgICAgZ3VhcmQgcDEuYXJndW1lbnRMYWJlbCA9PSBwMi5hcmd1bWVudExhYmVsIGVsc2UgeyByZXR1cm4gZmFsc2UgfQogICAgICAgIGd1YXJkIHAxLm5hbWUgPT0gcDIubmFtZSBlbHNlIHsgcmV0dXJuIGZhbHNlIH0KICAgICAgICBndWFyZCBwMS5hcmd1bWVudExhYmVsID09IHAyLmFyZ3VtZW50TGFiZWwgZWxzZSB7IHJldHVybiBmYWxzZSB9CiAgICAgICAgZ3VhcmQgcDEudHlwZU5hbWUubmFtZSA9PSBwMi50eXBlTmFtZS5uYW1lIGVsc2UgeyByZXR1cm4gZmFsc2UgfQogICAgICAgIGd1YXJkIHAxLmFjdHVhbFR5cGVOYW1lPy5uYW1lID09IHAyLmFjdHVhbFR5cGVOYW1lPy5uYW1lIGVsc2UgeyByZXR1cm4gZmFsc2UgfQogICAgICAgIHJldHVybiB0cnVlCiAgICB9CgogICAgZnVuYyBhcmVTYW1lTWV0aG9kcyhfIG0xOiBTb3VyY2VyeVJ1bnRpbWUuTWV0aG9kLCBfIG0yOiBTb3VyY2VyeVJ1bnRpbWUuTWV0aG9kKSAtPiBCb29sIHsKICAgICAgICBndWFyZCBtMS5uYW1lICE9IG0yLm5hbWUgZWxzZSB7IHJldHVybiByZXR1cm5UeXBlU3RyaXBwZWQobTEpID09IHJldHVyblR5cGVTdHJpcHBlZChtMikgfQogICAgICAgIGd1YXJkIG0xLnNlbGVjdG9yTmFtZSA9PSBtMi5zZWxlY3Rvck5hbWUgZWxzZSB7IHJldHVybiBmYWxzZSB9CiAgICAgICAgZ3VhcmQgbTEucGFyYW1ldGVycy5jb3VudCA9PSBtMi5wYXJhbWV0ZXJzLmNvdW50IGVsc2UgeyByZXR1cm4gZmFsc2UgfQoKICAgICAgICBsZXQgcDEgPSBtMS5wYXJhbWV0ZXJzCiAgICAgICAgbGV0IHAyID0gbTIucGFyYW1ldGVycwoKICAgICAgICBmb3IgaSBpbiAwLi48cDEuY291bnQgewogICAgICAgICAgICBpZiAhYXJlU2FtZVBhcmFtcyhwMVtpXSxwMltpXSkgeyByZXR1cm4gZmFsc2UgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHJldHVyblR5cGVTdHJpcHBlZChtMSkgPT0gcmV0dXJuVHlwZVN0cmlwcGVkKG0yKQogICAgfQoKICAgIHJldHVybiBtZXRob2RzLnJlZHVjZShbXSwgeyAocmVzdWx0LCBlbGVtZW50KSAtPiBbU291cmNlcnlSdW50aW1lLk1ldGhvZF0gaW4KICAgICAgICBndWFyZCAhcmVzdWx0LmNvbnRhaW5zKHdoZXJlOiB7IGFyZVNhbWVNZXRob2RzKCQwLGVsZW1lbnQpIH0pIGVsc2UgeyByZXR1cm4gcmVzdWx0IH0KICAgICAgICByZXR1cm4gcmVzdWx0ICsgW2VsZW1lbnRdCiAgICB9KQp9CgpmdW5jIHVuaXF1ZXModmFyaWFibGVzOiBbU291cmNlcnlSdW50aW1lLlZhcmlhYmxlXSkgLT4gW1NvdXJjZXJ5UnVudGltZS5WYXJpYWJsZV0gewogICAgcmV0dXJuIHZhcmlhYmxlcy5yZWR1Y2UoW10sIHsgKHJlc3VsdCwgZWxlbWVudCkgLT4gW1NvdXJjZXJ5UnVudGltZS5WYXJpYWJsZV0gaW4KICAgICAgICBndWFyZCAhcmVzdWx0LmNvbnRhaW5zKHdoZXJlOiB7ICQwLm5hbWUgPT0gZWxlbWVudC5uYW1lIH0pIGVsc2UgeyByZXR1cm4gcmVzdWx0IH0KICAgICAgICByZXR1cm4gcmVzdWx0ICsgW2VsZW1lbnRdCiAgICB9KQp9CgpmdW5jIHdyYXBNZXRob2QoXyBtZXRob2Q6IFNvdXJjZXJ5UnVudGltZS5NZXRob2QpIC0+IE1ldGhvZFdyYXBwZXIgewogICAgcmV0dXJuIE1ldGhvZFdyYXBwZXIobWV0aG9kKQp9CgpmdW5jIHdyYXBTdWJzY3JpcHQoXyB3cmFwcGVkOiBTb3VyY2VyeVJ1bnRpbWUuU3Vic2NyaXB0KSAtPiBTdWJzY3JpcHRXcmFwcGVyIHsKICAgIHJldHVybiBTdWJzY3JpcHRXcmFwcGVyKHdyYXBwZWQpCn0KCmZ1bmMganVzdFdyYXAoXyB2YXJpYWJsZTogU291cmNlcnlSdW50aW1lLlZhcmlhYmxlKSAtPiBWYXJpYWJsZVdyYXBwZXIgeyByZXR1cm4gd3JhcFByb3BlcnR5KHZhcmlhYmxlKSB9CmZ1bmMgd3JhcFByb3BlcnR5KF8gdmFyaWFibGU6IFNvdXJjZXJ5UnVudGltZS5WYXJpYWJsZSwgXyBzY29wZTogU3RyaW5nID0gIiIpIC0+IFZhcmlhYmxlV3JhcHBlciB7CiAgICByZXR1cm4gVmFyaWFibGVXcmFwcGVyKHZhcmlhYmxlLCBzY29wZTogc2NvcGUpCn0KCmZ1bmMgc3R1YlByb3BlcnR5KF8gdmFyaWFibGU6IFNvdXJjZXJ5UnVudGltZS5WYXJpYWJsZSwgXyBzY29wZTogU3RyaW5nKSAtPiBTdHJpbmcgewogICAgbGV0IHdyYXBwZXIgPSBWYXJpYWJsZVdyYXBwZXIodmFyaWFibGUsIHNjb3BlOiBzY29wZSkKICAgIHJldHVybiAiXCh3cmFwcGVyLnByb3RvdHlwZSlcblx0XCh3cmFwcGVyLnByaXZhdGVQcm90b3R5cGUpIgp9CgpmdW5jIHByb3BlcnR5VHlwZXMoXyB2YXJpYWJsZTogU291cmNlcnlSdW50aW1lLlZhcmlhYmxlKSAtPiBTdHJpbmcgewogICAgbGV0IHdyYXBwZXIgPSBWYXJpYWJsZVdyYXBwZXIodmFyaWFibGUsIHNjb3BlOiAic2NvcGUiKQogICAgcmV0dXJuICJcKHdyYXBwZXIucHJvcGVydHlHZXQoKSkiICsgKHdyYXBwZXIucmVhZG9ubHkgPyAiIiA6ICJcblx0XHRcKHdyYXBwZXIucHJvcGVydHlTZXQoKSkiKQp9CgpmdW5jIHByb3BlcnR5TWV0aG9kVHlwZXMoXyB2YXJpYWJsZTogU291cmNlcnlSdW50aW1lLlZhcmlhYmxlKSAtPiBTdHJpbmcgewogICAgbGV0IHdyYXBwZXIgPSBWYXJpYWJsZVdyYXBwZXIodmFyaWFibGUsIHNjb3BlOiAiIikKICAgIHJldHVybiAiXCh3cmFwcGVyLnByb3BlcnR5Q2FzZUdldCgpKSIgKyAod3JhcHBlci5yZWFkb25seSA/ICIiIDogIlxuXHRcdFwod3JhcHBlci5wcm9wZXJ0eUNhc2VTZXQoKSkiKQp9CgpmdW5jIHByb3BlcnR5TWV0aG9kVHlwZXNJbnRWYWx1ZShfIHZhcmlhYmxlOiBTb3VyY2VyeVJ1bnRpbWUuVmFyaWFibGUpIC0+IFN0cmluZyB7CiAgICBsZXQgd3JhcHBlciA9IFZhcmlhYmxlV3JhcHBlcih2YXJpYWJsZSwgc2NvcGU6ICIiKQogICAgcmV0dXJuICJcKHdyYXBwZXIucHJvcGVydHlDYXNlR2V0SW50VmFsdWUoKSkiICsgKHdyYXBwZXIucmVhZG9ubHkgPyAiIiA6ICJcblx0XHRcdFwod3JhcHBlci5wcm9wZXJ0eUNhc2VTZXRJbnRWYWx1ZSgpKSIpCn0KCmZ1bmMgcHJvcGVydHlSZWdpc3RlcihfIHZhcmlhYmxlOiBTb3VyY2VyeVJ1bnRpbWUuVmFyaWFibGUpIHsKICAgIGxldCB3cmFwcGVyID0gVmFyaWFibGVXcmFwcGVyKHZhcmlhYmxlLCBzY29wZTogIiIpCiAgICBNZXRob2RXcmFwcGVyLnJlZ2lzdGVyKHdyYXBwZXIucHJvcGVydHlDYXNlR2V0TmFtZSx3cmFwcGVyLnByb3BlcnR5Q2FzZUdldE5hbWUsd3JhcHBlci5wcm9wZXJ0eUNhc2VHZXROYW1lKQogICAgZ3VhcmQgIXdyYXBwZXIucmVhZG9ubHkgZWxzZSB7IHJldHVybiB9CiAgICBNZXRob2RXcmFwcGVyLnJlZ2lzdGVyKHdyYXBwZXIucHJvcGVydHlDYXNlU2V0TmFtZSx3cmFwcGVyLnByb3BlcnR5Q2FzZVNldE5hbWUsd3JhcHBlci5wcm9wZXJ0eUNhc2VHZXROYW1lKQp9CmNsYXNzIEhlbHBlcnMgewogICAgc3RhdGljIGZ1bmMgc3BsaXQoXyBzdHJpbmc6IFN0cmluZywgYnlGaXJzdE9jY3VyZW5jZU9mIHdvcmQ6IFN0cmluZykgLT4gKFN0cmluZywgU3RyaW5nKSB7CiAgICAgICAgZ3VhcmQgbGV0IHdvcmRSYW5nZSA9IHN0cmluZy5yYW5nZShvZjogd29yZCkgZWxzZSB7IHJldHVybiAoc3RyaW5nLCAiIikgfQogICAgICAgIGxldCBzZWxmUmFuZ2UgPSBzdHJpbmcucmFuZ2Uob2Y6IHN0cmluZykhCiAgICAgICAgbGV0IGJlZm9yZSA9IFN0cmluZyhzdHJpbmdbc2VsZlJhbmdlLmxvd2VyQm91bmQuLjx3b3JkUmFuZ2UubG93ZXJCb3VuZF0pCiAgICAgICAgbGV0IGFmdGVyID0gU3RyaW5nKHN0cmluZ1t3b3JkUmFuZ2UudXBwZXJCb3VuZC4uPHNlbGZSYW5nZS51cHBlckJvdW5kXSkKICAgICAgICByZXR1cm4gKGJlZm9yZSwgYWZ0ZXIpCiAgICB9CiAgICBzdGF0aWMgZnVuYyBleHRyYWN0QXNzb2NpYXRlZFR5cGVzKGZyb20gYW5ub3RhdGVkOiBTb3VyY2VyeVJ1bnRpbWUuQW5ub3RhdGVkKSAtPiBbU3RyaW5nXT8gewogICAgICAgIGlmIGxldCB0eXBlcyA9IGFubm90YXRlZC5hbm5vdGF0aW9uc1siYXNzb2NpYXRlZHR5cGUiXSBhcz8gW1N0cmluZ10gewogICAgICAgICAgICByZXR1cm4gdHlwZXMucmV2ZXJzZWQoKQogICAgICAgIH0gZWxzZSBpZiBsZXQgdHlwZSA9IGFubm90YXRlZC5hbm5vdGF0aW9uc1siYXNzb2NpYXRlZHR5cGUiXSBhcz8gU3RyaW5nIHsKICAgICAgICAgICAgcmV0dXJuIFt0eXBlXQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBuaWwKICAgICAgICB9CiAgICB9CiAgICBzdGF0aWMgZnVuYyBleHRyYWN0V2hlcmVDbGF1c2UoZnJvbSBhbm5vdGF0ZWQ6IFNvdXJjZXJ5UnVudGltZS5Bbm5vdGF0ZWQpIC0+IFN0cmluZz8gewogICAgICAgIGlmIGxldCBjb25zdHJhaW50cyA9IGFubm90YXRlZC5hbm5vdGF0aW9uc1sid2hlcmUiXSBhcz8gW1N0cmluZ10gewogICAgICAgICAgICByZXR1cm4gIiB3aGVyZSBcKGNvbnN0cmFpbnRzLnJldmVyc2VkKCkuam9pbmVkKHNlcGFyYXRvcjogIiwgIikpIgogICAgICAgIH0gZWxzZSBpZiBsZXQgY29uc3RyYWludCA9IGFubm90YXRlZC5hbm5vdGF0aW9uc1sid2hlcmUiXSBhcz8gU3RyaW5nIHsKICAgICAgICAgICAgcmV0dXJuICIgd2hlcmUgXChjb25zdHJhaW50KSIKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gbmlsCiAgICAgICAgfQogICAgfQogICAgLy8vIEV4dHJhY3QgYWxsIHR5cGVhbGlhc2VzIGZyb20gImFubm90YXRpb25zIgogICAgc3RhdGljIGZ1bmMgZXh0cmFjdFR5cGVhbGlhc2VzKGZyb20gYW5ub3RhdGVkOiBTb3VyY2VyeVJ1bnRpbWUuQW5ub3RhdGVkKSAtPiBbU3RyaW5nXSB7CiAgICAgICAgaWYgbGV0IHR5cGVzID0gYW5ub3RhdGVkLmFubm90YXRpb25zWyJ0eXBlYWxpYXMiXSBhcz8gW1N0cmluZ10gewogICAgICAgICAgICByZXR1cm4gdHlwZXMucmV2ZXJzZWQoKQogICAgICAgIH0gZWxzZSBpZiBsZXQgdHlwZSA9IGFubm90YXRlZC5hbm5vdGF0aW9uc1sidHlwZWFsaWFzIl0gYXM/IFN0cmluZyB7CiAgICAgICAgICAgIHJldHVybiBbdHlwZV0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gW10KICAgICAgICB9CiAgICB9CiAgICBzdGF0aWMgZnVuYyBleHRyYWN0R2VuZXJpY3NMaXN0KF8gYXNzb2NpYXRlZFR5cGVzOiBbU3RyaW5nXT8pIC0+IFtTdHJpbmddIHsKICAgICAgICByZXR1cm4gYXNzb2NpYXRlZFR5cGVzPy5mbGF0TWFwIHsKICAgICAgICAgICAgc3BsaXQoJDAsIGJ5Rmlyc3RPY2N1cmVuY2VPZjogIiB3aGVyZSAiKS4wLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiICIsIHdpdGg6ICIiKS5jaGFyYWN0ZXJzLnNwbGl0KHNlcGFyYXRvcjogIjoiKS5tYXAoU3RyaW5nLmluaXQpLmZpcnN0CiAgICAgICAgfS5tYXAgeyAiXCgkMCkiIH0gPz8gW10KICAgIH0KICAgIHN0YXRpYyBmdW5jIGV4dHJhY3RHZW5lcmljVHlwZXNNb2RpZmllcihfIGFzc29jaWF0ZWRUeXBlczogW1N0cmluZ10/KSAtPiBTdHJpbmcgewogICAgICAgIGxldCBhbGwgPSBleHRyYWN0R2VuZXJpY3NMaXN0KGFzc29jaWF0ZWRUeXBlcykKICAgICAgICBndWFyZCAhYWxsLmlzRW1wdHkgZWxzZSB7IHJldHVybiAiIiB9CiAgICAgICAgcmV0dXJuICI8XChhbGwuam9pbmVkKHNlcGFyYXRvcjogIiwiKSk+IgogICAgfQogICAgc3RhdGljIGZ1bmMgZXh0cmFjdEdlbmVyaWNUeXBlc0NvbnN0cmFpbnRzKF8gYXNzb2NpYXRlZFR5cGVzOiBbU3RyaW5nXT8pIC0+IFN0cmluZyB7CiAgICAgICAgZ3VhcmQgbGV0IGFsbCA9IGFzc29jaWF0ZWRUeXBlcyBlbHNlIHsgcmV0dXJuICIiIH0KICAgICAgICBsZXQgY29uc3RyYWludHMgPSBhbGwuZmxhdE1hcCB7IHQgLT4gU3RyaW5nPyBpbgogICAgICAgICAgICBsZXQgc3BsaXR0ZWQgPSBzcGxpdCh0LCBieUZpcnN0T2NjdXJlbmNlT2Y6ICIgd2hlcmUgIikKICAgICAgICAgICAgbGV0IGNvbnN0cmFpbnQgPSBzcGxpdHRlZC4wLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiICIsIHdpdGg6ICIiKS5jaGFyYWN0ZXJzLnNwbGl0KHNlcGFyYXRvcjogIjoiKS5tYXAoU3RyaW5nLmluaXQpCiAgICAgICAgICAgIGd1YXJkIGNvbnN0cmFpbnQuY291bnQgPT0gMiBlbHNlIHsgcmV0dXJuIG5pbCB9CiAgICAgICAgICAgIGxldCBhZG9wdHMgPSBjb25zdHJhaW50WzFdLmNoYXJhY3RlcnMuc3BsaXQoc2VwYXJhdG9yOiAiLCIpLm1hcChTdHJpbmcuaW5pdCkKICAgICAgICAgICAgdmFyIG1hcHBlZCA9IGFkb3B0cy5tYXAgeyAiXChjb25zdHJhaW50WzBdKTogXCgkMCkiIH0KICAgICAgICAgICAgaWYgIXNwbGl0dGVkLjEuaXNFbXB0eSB7CiAgICAgICAgICAgICAgICBtYXBwZWQuYXBwZW5kKHNwbGl0dGVkLjEpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG1hcHBlZC5qb2luZWQoc2VwYXJhdG9yOiAiLCAiKQogICAgICAgICAgICB9CiAgICAgICAgICAgIC5qb2luZWQoc2VwYXJhdG9yOiAiLCAiKQogICAgICAgIGd1YXJkICFjb25zdHJhaW50cy5pc0VtcHR5IGVsc2UgeyByZXR1cm4gIiIgfQogICAgICAgIHJldHVybiAiIHdoZXJlIFwoY29uc3RyYWludHMpIgogICAgfQogICAgc3RhdGljIGZ1bmMgZXh0cmFjdEF0dHJpYnV0ZXMoCiAgICAgICAgZnJvbSBhdHRyaWJ1dGVzOiBbU3RyaW5nOiBbU291cmNlcnlSdW50aW1lLkF0dHJpYnV0ZV1dLAogICAgICAgIGZpbHRlck91dFN0YXJ0aW5nV2l0aCBkaXNhbGxvd2VkUHJlZml4ZXM6IFtTdHJpbmddID0gW10KICAgICkgLT4gU3RyaW5nIHsKICAgICAgICByZXR1cm4gYXR0cmlidXRlcwogICAgICAgIC5yZWR1Y2UoW1NvdXJjZXJ5UnVudGltZS5BdHRyaWJ1dGVdKCkpIHsgJDAgKyAkMS4xIH0KICAgICAgICAubWFwIHsgJDAuZGVzY3JpcHRpb24gfQogICAgICAgIC5maWx0ZXIgeyAhWyJwcml2YXRlIiwgImludGVybmFsIiwgInB1YmxpYyIsICJvcGVuIiwgIm9wdGlvbmFsIl0uY29udGFpbnMoJDApIH0KICAgICAgICAuZmlsdGVyIHsgZWxlbWVudCBpbgogICAgICAgICAgICAhZGlzYWxsb3dlZFByZWZpeGVzLmNvbnRhaW5zKHdoZXJlOiBlbGVtZW50Lmhhc1ByZWZpeCkKICAgICAgICB9CiAgICAgICAgLnNvcnRlZCgpCiAgICAgICAgLmpvaW5lZChzZXBhcmF0b3I6ICIgIikKICAgIH0KfQpjbGFzcyBQYXJhbWV0ZXJXcmFwcGVyIHsKICAgIGxldCBwYXJhbWV0ZXI6IE1ldGhvZFBhcmFtZXRlcgoKICAgIHZhciBpc1ZhcmlhZGljID0gZmFsc2UKCiAgICB2YXIgd3JhcHBlZEZvckNhbGw6IFN0cmluZyB7CiAgICAgICAgbGV0IHR5cGVTdHJpbmcgPSAiXCh0eXBlLmFjdHVhbFR5cGVOYW1lID8/IHR5cGUpIgogICAgICAgIGxldCBpc0VzY2FwaW5nID0gdHlwZVN0cmluZy5jb250YWlucygiQGVzY2FwaW5nIikKICAgICAgICBsZXQgaXNPcHRpb25hbCA9ICh0eXBlLmFjdHVhbFR5cGVOYW1lID8/IHR5cGUpLmlzT3B0aW9uYWwKICAgICAgICBpZiBwYXJhbWV0ZXIuaXNDbG9zdXJlICYmICFpc0VzY2FwaW5nICYmICFpc09wdGlvbmFsIHsKICAgICAgICAgICAgcmV0dXJuICJcKG5lc3RlZFR5cGUpLmFueSIKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gIlwobmVzdGVkVHlwZSkudmFsdWUoXChlc2NhcGVkTmFtZSkpIgogICAgICAgIH0KICAgIH0KICAgIHZhciBuZXN0ZWRUeXBlOiBTdHJpbmcgewogICAgICAgIHJldHVybiAiXChUeXBlV3JhcHBlcih0eXBlLCBpc1ZhcmlhZGljKS5uZXN0ZWRQYXJhbWV0ZXIpIgogICAgfQogICAgdmFyIGp1c3RUeXBlOiBTdHJpbmcgewogICAgICAgIHJldHVybiAiXChUeXBlV3JhcHBlcih0eXBlLCBpc1ZhcmlhZGljKS5yZXBsYWNpbmdTZWxmKCkpIgogICAgfQogICAgdmFyIGp1c3RQZXJmb3JtVHlwZTogU3RyaW5nIHsKICAgICAgICByZXR1cm4gIlwoVHlwZVdyYXBwZXIodHlwZSwgaXNWYXJpYWRpYykucmVwbGFjaW5nU2VsZlJlc3BlY3RpbmdWYXJpYWRpYygpKSIucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICIhIiwgd2l0aDogIj8iKQogICAgfQogICAgdmFyIGdlbmVyaWNUeXBlOiBTdHJpbmcgewogICAgICAgIHJldHVybiBpc1ZhcmlhZGljID8gIlBhcmFtZXRlcjxbR2VuZXJpY0F0dHJpYnV0ZV0+IiA6ICJQYXJhbWV0ZXI8R2VuZXJpY0F0dHJpYnV0ZT4iCiAgICB9CiAgICB2YXIgdHlwZUVyYXNlZFR5cGU6IFN0cmluZyB7CiAgICAgICAgcmV0dXJuIGlzVmFyaWFkaWMgPyAiUGFyYW1ldGVyPFtUeXBlRXJhc2VkQXR0cmlidXRlXT4iIDogIlBhcmFtZXRlcjxUeXBlRXJhc2VkQXR0cmlidXRlPiIKICAgIH0KICAgIHZhciB0eXBlOiBTb3VyY2VyeVJ1bnRpbWUuVHlwZU5hbWUgewogICAgICAgIHJldHVybiBwYXJhbWV0ZXIudHlwZU5hbWUKICAgIH0KICAgIHZhciBuYW1lOiBTdHJpbmcgewogICAgICAgIHJldHVybiBwYXJhbWV0ZXIubmFtZQogICAgfQogICAgdmFyIGVzY2FwZWROYW1lOiBTdHJpbmcgewogICAgICAgIHJldHVybiAiYFwocGFyYW1ldGVyLm5hbWUpYCIKICAgIH0KICAgIHZhciBjb21wYXJhdG9yOiBTdHJpbmcgewogICAgICAgIHJldHVybiAiZ3VhcmQgUGFyYW1ldGVyLmNvbXBhcmUobGhzOiBsaHNcKHBhcmFtZXRlci5uYW1lLmNhcGl0YWxpemVkKSwgcmhzOiByaHNcKHBhcmFtZXRlci5uYW1lLmNhcGl0YWxpemVkKSwgd2l0aDogbWF0Y2hlcikgZWxzZSB7IHJldHVybiBmYWxzZSB9IgogICAgfQogICAgZnVuYyBjb21wYXJhdG9yUmVzdWx0KCkgLT4gU3RyaW5nIHsKICAgICAgICBsZXQgbGhzTmFtZSA9ICJsaHNcKHBhcmFtZXRlci5uYW1lLmNhcGl0YWxpemVkKSIKICAgICAgICBsZXQgcmhzTmFtZSA9ICJyaHNcKHBhcmFtZXRlci5uYW1lLmNhcGl0YWxpemVkKSIKICAgICAgICByZXR1cm4gInJlc3VsdHMuYXBwZW5kKE1hdGNoZXIuUGFyYW1ldGVyQ29tcGFyaXNvblJlc3VsdChQYXJhbWV0ZXIuY29tcGFyZShsaHM6IFwobGhzTmFtZSksIHJoczogXChyaHNOYW1lKSwgd2l0aDogbWF0Y2hlciksIFwobGhzTmFtZSksIFwocmhzTmFtZSksIFwiXChsYWJlbEFuZE5hbWUoKSlcIikpIgogICAgfQoKICAgIGluaXQoXyBwYXJhbWV0ZXI6IFNvdXJjZXJ5UnVudGltZS5NZXRob2RQYXJhbWV0ZXIsIF8gdmFyaWFkaWNzOiBbU3RyaW5nXSA9IFtdKSB7CiAgICAgICAgc2VsZi5wYXJhbWV0ZXIgPSBwYXJhbWV0ZXIKICAgICAgICBzZWxmLmlzVmFyaWFkaWMgPSAhdmFyaWFkaWNzLmlzRW1wdHkgJiYgdmFyaWFkaWNzLmNvbnRhaW5zKHBhcmFtZXRlci5uYW1lKQogICAgfQoKICAgIGZ1bmMgaXNHZW5lcmljKF8gdHlwZXM6IFtTdHJpbmddKSAtPiBCb29sIHsKICAgICAgICByZXR1cm4gVHlwZVdyYXBwZXIodHlwZSkuaXNHZW5lcmljKHR5cGVzKQogICAgfQoKICAgIGZ1bmMgd3JhcHBlZEZvclByb3h5KF8gZ2VuZXJpY3M6IFtTdHJpbmddLCBfIGF2YWlsYWJpbGl0eTogQm9vbCA9IGZhbHNlKSAtPiBTdHJpbmcgewogICAgICAgIGlmIGlzR2VuZXJpYyhnZW5lcmljcykgewogICAgICAgICAgICByZXR1cm4gIlwoZXNjYXBlZE5hbWUpLndyYXBBc0dlbmVyaWMoKSIKICAgICAgICB9CiAgICAgICAgaWYgKGF2YWlsYWJpbGl0eSkgewogICAgICAgICAgICByZXR1cm4gIlwoZXNjYXBlZE5hbWUpLnR5cGVFcmFzZWRBdHRyaWJ1dGUoKSIKICAgICAgICB9CiAgICAgICAgcmV0dXJuICJcKGVzY2FwZWROYW1lKSIKICAgIH0KICAgIGZ1bmMgd3JhcHBlZEZvckNhbGxzKF8gZ2VuZXJpY3M6IFtTdHJpbmddLCBfIGF2YWlsYWJpbGl0eTogQm9vbCA9IGZhbHNlKSAtPiBTdHJpbmcgewogICAgICAgIGlmIGlzR2VuZXJpYyhnZW5lcmljcykgewogICAgICAgICAgICByZXR1cm4gIlwod3JhcHBlZEZvckNhbGwpLndyYXBBc0dlbmVyaWMoKSIKICAgICAgICB9CiAgICAgICAgaWYgKGF2YWlsYWJpbGl0eSkgewogICAgICAgICAgICByZXR1cm4gIlwod3JhcHBlZEZvckNhbGwpLnR5cGVFcmFzZWRBdHRyaWJ1dGUoKSIKICAgICAgICB9CiAgICAgICAgcmV0dXJuICJcKHdyYXBwZWRGb3JDYWxsKSIKICAgIH0KCiAgICBmdW5jIGFzTWV0aG9kQXJndW1lbnQoKSAtPiBTdHJpbmcgewogICAgICAgIGlmIHBhcmFtZXRlci5hcmd1bWVudExhYmVsICE9IHBhcmFtZXRlci5uYW1lIHsKICAgICAgICAgICAgcmV0dXJuICJcKHBhcmFtZXRlci5hcmd1bWVudExhYmVsID8/ICJfIikgXChwYXJhbWV0ZXIubmFtZSk6IFwocGFyYW1ldGVyLnR5cGVOYW1lKSIKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gIlwocGFyYW1ldGVyLm5hbWUpOiBcKHBhcmFtZXRlci50eXBlTmFtZSkiCiAgICAgICAgfQogICAgfQogICAgZnVuYyBsYWJlbEFuZE5hbWUoKSAtPiBTdHJpbmcgewogICAgICAgIGxldCBsYWJlbCA9IHBhcmFtZXRlci5hcmd1bWVudExhYmVsID8/ICJfIgogICAgICAgIHJldHVybiBsYWJlbCAhPSBwYXJhbWV0ZXIubmFtZSA/ICJcKGxhYmVsKSBcKHBhcmFtZXRlci5uYW1lKSIgOiBsYWJlbAogICAgfQogICAgZnVuYyBzYW5pdGl6ZWRGb3JFbnVtQ2FzZU5hbWUoKSAtPiBTdHJpbmcgewogICAgICAgIGlmIGxldCBsYWJlbCA9IHBhcmFtZXRlci5hcmd1bWVudExhYmVsLCBsYWJlbCAhPSBwYXJhbWV0ZXIubmFtZSB7CiAgICAgICAgICAgIHJldHVybiAiXChsYWJlbClfXChwYXJhbWV0ZXIubmFtZSkiLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiYCIsIHdpdGg6ICIiKQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAiXChwYXJhbWV0ZXIubmFtZSkiLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiYCIsIHdpdGg6ICIiKQogICAgICAgIH0KICAgIH0KfQpjbGFzcyBUeXBlV3JhcHBlciB7CiAgICBsZXQgdHlwZTogU291cmNlcnlSdW50aW1lLlR5cGVOYW1lCiAgICBsZXQgaXNWYXJpYWRpYzogQm9vbAoKICAgIHZhciB2UHJlZjogU3RyaW5nIHsgcmV0dXJuIGlzVmFyaWFkaWMgPyAiWyIgOiAiIiB9CiAgICB2YXIgdlN1ZmY6IFN0cmluZyB7IHJldHVybiBpc1ZhcmlhZGljID8gIl0iIDogIiIgfQoKICAgIHZhciB1bndyYXBwZWQ6IFN0cmluZyB7CiAgICAgICAgcmV0dXJuIHR5cGUudW53cmFwcGVkVHlwZU5hbWUKICAgIH0KICAgIHZhciB1bndyYXBwZWRSZXBsYWNpbmdTZWxmOiBTdHJpbmcgewogICAgICAgIHJldHVybiByZXBsYWNpbmdTZWxmKHVud3JhcDogdHJ1ZSkKICAgIH0KICAgIHZhciBzdHJpcHBlZDogU3RyaW5nIHsKICAgICAgICBpZiB0eXBlLmlzSW1wbGljaXRseVVud3JhcHBlZE9wdGlvbmFsIHsKICAgICAgICAgICAgcmV0dXJuICJcKHZQcmVmKVwodW53cmFwcGVkUmVwbGFjaW5nU2VsZik/XCh2U3VmZikiCiAgICAgICAgfSBlbHNlIGlmIHR5cGUuaXNPcHRpb25hbCB7CiAgICAgICAgICAgIHJldHVybiAiXCh2UHJlZilcKHVud3JhcHBlZFJlcGxhY2luZ1NlbGYpP1wodlN1ZmYpIgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAiXCh2UHJlZilcKHVud3JhcHBlZFJlcGxhY2luZ1NlbGYpXCh2U3VmZikiCiAgICAgICAgfQogICAgfQogICAgdmFyIG5lc3RlZFBhcmFtZXRlcjogU3RyaW5nIHsKICAgICAgICBpZiB0eXBlLmlzSW1wbGljaXRseVVud3JhcHBlZE9wdGlvbmFsIHsKICAgICAgICAgICAgcmV0dXJuICJQYXJhbWV0ZXI8XCh2UHJlZilcKHVud3JhcHBlZFJlcGxhY2luZ1NlbGYpP1wodlN1ZmYpPiIKICAgICAgICB9IGVsc2UgaWYgdHlwZS5pc09wdGlvbmFsIHsKICAgICAgICAgICAgcmV0dXJuICJQYXJhbWV0ZXI8XCh2UHJlZilcKHVud3JhcHBlZFJlcGxhY2luZ1NlbGYpP1wodlN1ZmYpPiIKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gIlBhcmFtZXRlcjxcKHZQcmVmKVwodW53cmFwcGVkUmVwbGFjaW5nU2VsZilcKHZTdWZmKT4iCiAgICAgICAgfQogICAgfQogICAgdmFyIGlzU2VsZlR5cGU6IEJvb2wgewogICAgICAgIHJldHVybiB1bndyYXBwZWQgPT0gIlNlbGYiCiAgICB9CiAgICBmdW5jIGlzU2VsZlR5cGVSZWN1cnNpdmUoKSAtPiBCb29sIHsKICAgICAgICBpZiBsZXQgdHVwbGUgPSB0eXBlLnR1cGxlIHsKICAgICAgICAgICAgZm9yIGVsZW1lbnQgaW4gdHVwbGUuZWxlbWVudHMgewogICAgICAgICAgICAgICAgZ3VhcmQgIVR5cGVXcmFwcGVyKGVsZW1lbnQudHlwZU5hbWUpLmlzU2VsZlR5cGVSZWN1cnNpdmUoKSBlbHNlIHsgcmV0dXJuIHRydWUgfQogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIGxldCBhcnJheSA9IHR5cGUuYXJyYXkgewogICAgICAgICAgICByZXR1cm4gVHlwZVdyYXBwZXIoYXJyYXkuZWxlbWVudFR5cGVOYW1lKS5pc1NlbGZUeXBlUmVjdXJzaXZlKCkKICAgICAgICB9IGVsc2UgaWYgbGV0IGRpY3Rpb25hcnkgPSB0eXBlLmRpY3Rpb25hcnkgewogICAgICAgICAgICBndWFyZCAhVHlwZVdyYXBwZXIoZGljdGlvbmFyeS52YWx1ZVR5cGVOYW1lKS5pc1NlbGZUeXBlUmVjdXJzaXZlKCkgZWxzZSB7IHJldHVybiB0cnVlIH0KICAgICAgICAgICAgZ3VhcmQgIVR5cGVXcmFwcGVyKGRpY3Rpb25hcnkua2V5VHlwZU5hbWUpLmlzU2VsZlR5cGVSZWN1cnNpdmUoKSBlbHNlIHsgcmV0dXJuIHRydWUgfQogICAgICAgIH0gZWxzZSBpZiBsZXQgY2xvc3VyZSA9IHR5cGUuY2xvc3VyZSB7CiAgICAgICAgICAgIGd1YXJkICFUeXBlV3JhcHBlcihjbG9zdXJlLmFjdHVhbFJldHVyblR5cGVOYW1lKS5pc1NlbGZUeXBlUmVjdXJzaXZlKCkgZWxzZSB7IHJldHVybiB0cnVlIH0KICAgICAgICAgICAgZm9yIHBhcmFtZXRlciBpbiBjbG9zdXJlLnBhcmFtZXRlcnMgewogICAgICAgICAgICAgICAgZ3VhcmQgIVR5cGVXcmFwcGVyKHBhcmFtZXRlci50eXBlTmFtZSkuaXNTZWxmVHlwZVJlY3Vyc2l2ZSgpIGVsc2UgeyByZXR1cm4gdHJ1ZSB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBpc1NlbGZUeXBlCiAgICB9CgogICAgaW5pdChfIHR5cGU6IFNvdXJjZXJ5UnVudGltZS5UeXBlTmFtZSwgXyBpc1ZhcmlhZGljOiBCb29sID0gZmFsc2UpIHsKICAgICAgICBzZWxmLnR5cGUgPSB0eXBlCiAgICAgICAgc2VsZi5pc1ZhcmlhZGljID0gaXNWYXJpYWRpYwogICAgfQoKICAgIGZ1bmMgaXNHZW5lcmljKF8gdHlwZXM6IFtTdHJpbmddKSAtPiBCb29sIHsKICAgICAgICBndWFyZCAhdHlwZS5pc1ZvaWQgZWxzZSB7IHJldHVybiBmYWxzZSB9CgogICAgICAgIHJldHVybiBpc0dlbmVyaWMobmFtZTogdW53cmFwcGVkLCBnZW5lcmljczogdHlwZXMpCiAgICB9CgogICAgcHJpdmF0ZSBmdW5jIGlzR2VuZXJpYyhuYW1lOiBTdHJpbmcsIGdlbmVyaWNzOiBbU3RyaW5nXSkgLT4gQm9vbCB7CiAgICAgICAgbGV0IG5hbWUgPSAiKFwobmFtZS5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogIiAiLCB3aXRoOiAiIikpKSIKICAgICAgICBsZXQgbW9kaWZpZXJzID0gIltcXD9cXCFdKiIKICAgICAgICByZXR1cm4gZ2VuZXJpY3MuY29udGFpbnMod2hlcmU6IHsgZ2VuZXJpYyBpbgogICAgICAgICAgICBsZXQgd3JhcHBlZCA9ICIoW1xcKF1cKGdlbmVyaWMpXChtb2RpZmllcnMpW1xcKVxcLl0pIgogICAgICAgICAgICBsZXQgY29uc3RyYWludCA9ICIoWzwsXVwoZ2VuZXJpYylcKG1vZGlmaWVycylbPixcXC5dKSIKICAgICAgICAgICAgbGV0IGFycmF5cyA9ICIoW1xcWzpdXChnZW5lcmljKVwobW9kaWZpZXJzKVtcXF0sXFwuOl0pIgogICAgICAgICAgICBsZXQgdHVwbGVzID0gIihbXFwoLF1cKGdlbmVyaWMpXChtb2RpZmllcnMpWyxcXC5cXCldKSIKICAgICAgICAgICAgbGV0IGNsb3N1cmVzID0gIigoXFwtXFw+KVwoZ2VuZXJpYylcKG1vZGlmaWVycylbLFxcLlxcKV0pIgogICAgICAgICAgICBsZXQgcGF0dGVybiA9ICJcKHdyYXBwZWQpfFwoY29uc3RyYWludCl8XChhcnJheXMpfFwodHVwbGVzKXxcKGNsb3N1cmVzKSIKICAgICAgICAgICAgZ3VhcmQgbGV0IHJlZ2V4ID0gdHJ5PyBOU1JlZ3VsYXJFeHByZXNzaW9uKHBhdHRlcm46IHBhdHRlcm4pIGVsc2UgeyByZXR1cm4gZmFsc2UgfQogICAgICAgICAgICByZXR1cm4gcmVnZXguZmlyc3RNYXRjaChpbjogbmFtZSwgb3B0aW9uczogW10sIHJhbmdlOiBOU1JhbmdlKGxvY2F0aW9uOiAwLCBsZW5ndGg6IChuYW1lIGFzIE5TU3RyaW5nKS5sZW5ndGgpKSAhPSBuaWwKICAgICAgICB9KQogICAgfQoKICAgIGZ1bmMgcmVwbGFjaW5nU2VsZih1bndyYXA6IEJvb2wgPSBmYWxzZSkgLT4gU3RyaW5nIHsKICAgICAgICBndWFyZCBpc1NlbGZUeXBlUmVjdXJzaXZlKCkgZWxzZSB7CiAgICAgICAgICAgIHJldHVybiB1bndyYXAgPyBzZWxmLnVud3JhcHBlZCA6ICJcKHR5cGUpIgogICAgICAgIH0KCiAgICAgICAgaWYgaXNTZWxmVHlwZSB7CiAgICAgICAgICAgIGxldCBvcHRpb25hbGl0eTogU3RyaW5nID0gewogICAgICAgICAgICAgICAgaWYgdHlwZS5pc0ltcGxpY2l0bHlVbndyYXBwZWRPcHRpb25hbCB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICIhIgogICAgICAgICAgICAgICAgfSBlbHNlIGlmIHR5cGUuaXNPcHRpb25hbCB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICI/IgogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gIiIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSgpCiAgICAgICAgICAgIHJldHVybiB1bndyYXAgPyBDdXJyZW50LnNlbGZUeXBlIDogQ3VycmVudC5zZWxmVHlwZSArIG9wdGlvbmFsaXR5CiAgICAgICAgfSBlbHNlIGlmIGxldCB0dXBsZSA9IHR5cGUudHVwbGUgewogICAgICAgICAgICBsZXQgaW5uZXIgPSB0dXBsZS5lbGVtZW50cy5tYXAoeyBUeXBlV3JhcHBlcigkMC50eXBlTmFtZSkucmVwbGFjaW5nU2VsZigpIH0pLmpvaW5lZChzZXBhcmF0b3I6ICIsIikKICAgICAgICAgICAgbGV0IHZhbHVlID0gIihcKGlubmVyKSkiCiAgICAgICAgICAgIHJldHVybiB2YWx1ZQogICAgICAgIH0gZWxzZSBpZiBsZXQgYXJyYXkgPSB0eXBlLmFycmF5IHsKICAgICAgICAgICAgbGV0IHZhbHVlID0gIltcKFR5cGVXcmFwcGVyKGFycmF5LmVsZW1lbnRUeXBlTmFtZSkucmVwbGFjaW5nU2VsZigpKV0iCiAgICAgICAgICAgIHJldHVybiB2YWx1ZQogICAgICAgIH0gZWxzZSBpZiBsZXQgZGljdGlvbmFyeSA9IHR5cGUuZGljdGlvbmFyeSB7CiAgICAgICAgICAgIGxldCB2YWx1ZSA9ICJbIiArCiAgICAgICAgICAgICAgICAiXChUeXBlV3JhcHBlcihkaWN0aW9uYXJ5LnZhbHVlVHlwZU5hbWUpLnJlcGxhY2luZ1NlbGYoKSkiCiAgICAgICAgICAgICAgICArICI6IiArCiAgICAgICAgICAgICAgICAiXChUeXBlV3JhcHBlcihkaWN0aW9uYXJ5LmtleVR5cGVOYW1lKS5yZXBsYWNpbmdTZWxmKCkpIgogICAgICAgICAgICAgICAgKyAiXSIKICAgICAgICAgICAgcmV0dXJuIHZhbHVlCiAgICAgICAgfSBlbHNlIGlmIGxldCBjbG9zdXJlID0gdHlwZS5jbG9zdXJlIHsKICAgICAgICAgICAgbGV0IHJldHVyblR5cGUgPSBUeXBlV3JhcHBlcihjbG9zdXJlLmFjdHVhbFJldHVyblR5cGVOYW1lKS5yZXBsYWNpbmdTZWxmKCkKICAgICAgICAgICAgbGV0IGlubmVyID0gY2xvc3VyZS5wYXJhbWV0ZXJzCiAgICAgICAgICAgICAgICAubWFwIHsgVHlwZVdyYXBwZXIoJDAudHlwZU5hbWUpLnJlcGxhY2luZ1NlbGYoKSB9CiAgICAgICAgICAgICAgICAuam9pbmVkKHNlcGFyYXRvcjogIiwiKQogICAgICAgICAgICBsZXQgdGhyb3dpbmcgPSBjbG9zdXJlLnRocm93cyA/ICJ0aHJvd3MgIiA6ICIiCiAgICAgICAgICAgIGxldCB2YWx1ZSA9ICIoXChpbm5lcikpIFwodGhyb3dpbmcpLT4gXChyZXR1cm5UeXBlKSIKICAgICAgICAgICAgcmV0dXJuIHZhbHVlCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuICh1bndyYXAgPyBzZWxmLnVud3JhcHBlZCA6ICJcKHR5cGUpIikKICAgICAgICB9CiAgICB9CgogICAgZnVuYyByZXBsYWNpbmdTZWxmUmVzcGVjdGluZ1ZhcmlhZGljKCkgLT4gU3RyaW5nIHsKICAgICAgICByZXR1cm4gIlwodlByZWYpXChyZXBsYWNpbmdTZWxmKCkpXCh2U3VmZikiCiAgICB9Cn0KZnVuYyByZXBsYWNpbmdTZWxmKF8gdmFsdWU6IFN0cmluZykgLT4gU3RyaW5nIHsKICAgIHJldHVybiB2YWx1ZQogICAgICAgIC8vIFRPRE86IHByb3BlciByZWdleCBoZXJlCiAgICAgICAgLy8gZGVmYXVsdCA8IGNhc2UgPgogICAgICAgIC5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogIjxTZWxmPiIsIHdpdGg6ICI8XChDdXJyZW50LnNlbGZUeXBlKT4iKQogICAgICAgIC5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogIjxTZWxmICIsIHdpdGg6ICI8XChDdXJyZW50LnNlbGZUeXBlKSAiKQogICAgICAgIC5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogIjxTZWxmLiIsIHdpdGg6ICI8XChDdXJyZW50LnNlbGZUeXBlKS4iKQogICAgICAgIC5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogIjxTZWxmLCIsIHdpdGg6ICI8XChDdXJyZW50LnNlbGZUeXBlKSwiKQogICAgICAgIC5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogIjxTZWxmPyIsIHdpdGg6ICI8XChDdXJyZW50LnNlbGZUeXBlKT8iKQogICAgICAgIC5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogIiBTZWxmPiIsIHdpdGg6ICIgXChDdXJyZW50LnNlbGZUeXBlKT4iKQogICAgICAgIC5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogIixTZWxmPiIsIHdpdGg6ICIsXChDdXJyZW50LnNlbGZUeXBlKT4iKQogICAgICAgIC8vIChTZWxmKSAtPiBDYXNlCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiKFNlbGYpIiwgd2l0aDogIihcKEN1cnJlbnQuc2VsZlR5cGUpKSIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiKFNlbGYgIiwgd2l0aDogIihcKEN1cnJlbnQuc2VsZlR5cGUpICIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiKFNlbGYuIiwgd2l0aDogIihcKEN1cnJlbnQuc2VsZlR5cGUpLiIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiKFNlbGYsIiwgd2l0aDogIihcKEN1cnJlbnQuc2VsZlR5cGUpLCIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiKFNlbGY/Iiwgd2l0aDogIihcKEN1cnJlbnQuc2VsZlR5cGUpPyIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiIFNlbGYpIiwgd2l0aDogIiBcKEN1cnJlbnQuc2VsZlR5cGUpKSIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiLFNlbGYpIiwgd2l0aDogIixcKEN1cnJlbnQuc2VsZlR5cGUpKSIpCiAgICAgICAgLy8gbGl0ZXJhbHMKICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICJbU2VsZl0iLCB3aXRoOiAiW1woQ3VycmVudC5zZWxmVHlwZSldIikKICAgICAgICAvLyByaWdodAogICAgICAgIC5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogIltTZWxmICIsIHdpdGg6ICJbXChDdXJyZW50LnNlbGZUeXBlKSAiKQogICAgICAgIC5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogIltTZWxmLiIsIHdpdGg6ICJbXChDdXJyZW50LnNlbGZUeXBlKS4iKQogICAgICAgIC5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogIltTZWxmLCIsIHdpdGg6ICJbXChDdXJyZW50LnNlbGZUeXBlKSwiKQogICAgICAgIC5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogIltTZWxmOiIsIHdpdGg6ICJbXChDdXJyZW50LnNlbGZUeXBlKToiKQogICAgICAgIC5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogIltTZWxmPyIsIHdpdGg6ICJbXChDdXJyZW50LnNlbGZUeXBlKT8iKQogICAgICAgIC8vIGxlZnQKICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICIgU2VsZl0iLCB3aXRoOiAiIFwoQ3VycmVudC5zZWxmVHlwZSldIikKICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICIsU2VsZl0iLCB3aXRoOiAiLFwoQ3VycmVudC5zZWxmVHlwZSldIikKICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICI6U2VsZl0iLCB3aXRoOiAiOlwoQ3VycmVudC5zZWxmVHlwZSldIikKICAgICAgICAvLyB1bmtub3duCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiIFNlbGYgIiwgd2l0aDogIiBcKEN1cnJlbnQuc2VsZlR5cGUpICIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiIFNlbGYuIiwgd2l0aDogIiBcKEN1cnJlbnQuc2VsZlR5cGUpLiIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiIFNlbGYsIiwgd2l0aDogIiBcKEN1cnJlbnQuc2VsZlR5cGUpLCIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiIFNlbGY6Iiwgd2l0aDogIiBcKEN1cnJlbnQuc2VsZlR5cGUpOiIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiIFNlbGY/Iiwgd2l0aDogIiBcKEN1cnJlbnQuc2VsZlR5cGUpPyIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiLFNlbGYgIiwgd2l0aDogIixcKEN1cnJlbnQuc2VsZlR5cGUpICIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiLFNlbGYsIiwgd2l0aDogIixcKEN1cnJlbnQuc2VsZlR5cGUpLCIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiLFNlbGY/Iiwgd2l0aDogIixcKEN1cnJlbnQuc2VsZlR5cGUpPyIpCn0KCmNsYXNzIE1ldGhvZFdyYXBwZXIgewogICAgcHJpdmF0ZSB2YXIgbm9TdHViRGVmaW5lZE1lc3NhZ2U6IFN0cmluZyB7CiAgICAgICAgbGV0IG1ldGhvZE5hbWUgPSBtZXRob2QubmFtZS5jb25kZW5zZVdoaXRlc3BhY2UoKQogICAgICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICIoICIsIHdpdGg6ICIoIikKICAgICAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiICkiLCB3aXRoOiAiKSIpCiAgICAgICAgcmV0dXJuICJTdHViIHJldHVybiB2YWx1ZSBub3Qgc3BlY2lmaWVkIGZvciBcKG1ldGhvZE5hbWUpLiBVc2UgZ2l2ZW4iCiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyB2YXIgcmVnaXN0ZXJlZDogW1N0cmluZzogSW50XSA9IFs6XQogICAgcHJpdmF0ZSBzdGF0aWMgdmFyIHN1ZmZpeGVzOiBbU3RyaW5nOiBJbnRdID0gWzpdCiAgICBwcml2YXRlIHN0YXRpYyB2YXIgc3VmZml4ZXNXaXRob3V0UmV0dXJuVHlwZTogW1N0cmluZzogSW50XSA9IFs6XQoKICAgIGxldCBtZXRob2Q6IFNvdXJjZXJ5UnVudGltZS5NZXRob2QKICAgIHZhciBhY2Nlc3NNb2RpZmllcjogU3RyaW5nIHsKICAgICAgICBndWFyZCAhbWV0aG9kLmlzU3RhdGljIGVsc2UgeyByZXR1cm4gInB1YmxpYyBzdGF0aWMiIH0KICAgICAgICBndWFyZCAhcmV0dXJuc0dlbmVyaWNDb25zdHJhaW5lZFRvU2VsZiBlbHNlIHsgcmV0dXJuICJwdWJsaWMiIH0KICAgICAgICBndWFyZCAhcGFyYW1ldGVyc0NvbnRhaW5zU2VsZiBlbHNlIHsgcmV0dXJuICJwdWJsaWMiIH0KICAgICAgICByZXR1cm4gQ3VycmVudC5hY2Nlc3NNb2RpZmllcgogICAgfQogICAgdmFyIGhhc0F2YWlsYWJpbGl0eTogQm9vbCB7IG1ldGhvZC5hdHRyaWJ1dGVzWyJhdmFpbGFibGUiXT8uaXNFbXB0eSA9PSBmYWxzZSB9CiAgICB2YXIgaXNBc3luYzogQm9vbCB7CiAgICAgICAgc2VsZi5tZXRob2QuYW5ub3RhdGlvbnNbImFzeW5jIl0gIT0gbmlsCiAgICB9CgogICAgcHJpdmF0ZSB2YXIgcmVnaXN0cmF0aW9uTmFtZTogU3RyaW5nIHsKICAgICAgICB2YXIgcmF3TmFtZSA9IChtZXRob2QuaXNTdGF0aWMgPyAic20qXChtZXRob2Quc2VsZWN0b3JOYW1lKSIgOiAibSpcKG1ldGhvZC5zZWxlY3Rvck5hbWUpIikKICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICJfIiwgd2l0aDogIiIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiKCIsIHdpdGg6ICJfXyIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiKSIsIHdpdGg6ICIiKQoKICAgICAgICB2YXIgcGFyYW1ldGVyc05hbWVzID0gbWV0aG9kLnBhcmFtZXRlcnMubWFwIHsgIlwoJDAubmFtZSkiIH0KCiAgICAgICAgd2hpbGUgbGV0IHJhbmdlID0gcmF3TmFtZS5yYW5nZShvZjogIjoiKSwgbGV0IG5hbWUgPSBwYXJhbWV0ZXJzTmFtZXMuZmlyc3QgewogICAgICAgICAgICBwYXJhbWV0ZXJzTmFtZXMucmVtb3ZlRmlyc3QoKQogICAgICAgICAgICByYXdOYW1lLnJlcGxhY2VTdWJyYW5nZShyYW5nZSwgd2l0aDogIl9cKG5hbWUpIikKICAgICAgICB9CgogICAgICAgIGxldCB0cmltU2V0ID0gQ2hhcmFjdGVyU2V0KGNoYXJhY3RlcnNJbjogIl8iKQoKICAgICAgICByZXR1cm4gIHJhd05hbWUKICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICI6Iiwgd2l0aDogIiIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAibSoiLCB3aXRoOiAibV8iKQogICAgICAgIC5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogIl9fXyIsIHdpdGg6ICJfXyIpLnRyaW1taW5nQ2hhcmFjdGVycyhpbjogdHJpbVNldCkKICAgIH0KICAgIHByaXZhdGUgdmFyIHVuaXF1ZU5hbWU6IFN0cmluZyB7CiAgICAgICAgdmFyIHJhd05hbWUgPSAobWV0aG9kLmlzU3RhdGljID8gInNtX1wobWV0aG9kLnNlbGVjdG9yTmFtZSkiIDogIm1fXChtZXRob2Quc2VsZWN0b3JOYW1lKSIpCiAgICAgICAgdmFyIHBhcmFtZXRlcnNOYW1lcyA9IG1ldGhvZC5wYXJhbWV0ZXJzLm1hcCB7ICJcKCQwLm5hbWUpX29mX1woJDAudHlwZU5hbWUubmFtZSkiIH0KCiAgICAgICAgd2hpbGUgbGV0IHJhbmdlID0gcmF3TmFtZS5yYW5nZShvZjogIjoiKSwgbGV0IG5hbWUgPSBwYXJhbWV0ZXJzTmFtZXMuZmlyc3QgewogICAgICAgICAgICBwYXJhbWV0ZXJzTmFtZXMucmVtb3ZlRmlyc3QoKQogICAgICAgICAgICByYXdOYW1lLnJlcGxhY2VTdWJyYW5nZShyYW5nZSwgd2l0aDogIl9cKG5hbWUpIikKICAgICAgICB9CgogICAgICAgIHJldHVybiByYXdOYW1lLnRyaW1taW5nQ2hhcmFjdGVycyhpbjogQ2hhcmFjdGVyU2V0KGNoYXJhY3RlcnNJbjogIl8iKSkKICAgIH0KICAgIHByaXZhdGUgdmFyIHVuaXF1ZU5hbWVXaXRoUmV0dXJuVHlwZTogU3RyaW5nIHsKICAgICAgICBsZXQgcmV0dXJuVHlwZVJhdyA9ICJcKG1ldGhvZC5yZXR1cm5UeXBlTmFtZSkiCiAgICAgICAgdmFyIHJldHVyblR5cGVTdHJpcHBlZDogU3RyaW5nID0gewogICAgICAgICAgICBndWFyZCBsZXQgcmFuZ2UgPSByZXR1cm5UeXBlUmF3LnJhbmdlKG9mOiAid2hlcmUiKSBlbHNlIHsgcmV0dXJuIHJldHVyblR5cGVSYXcgfQogICAgICAgICAgICB2YXIgc3RyaXBwZWQgPSByZXR1cm5UeXBlUmF3CiAgICAgICAgICAgIHN0cmlwcGVkLnJlbW92ZVN1YnJhbmdlKChyYW5nZS5sb3dlckJvdW5kKS4uLikKICAgICAgICAgICAgcmV0dXJuIHN0cmlwcGVkCiAgICAgICAgfSgpCiAgICAgICAgcmV0dXJuVHlwZVN0cmlwcGVkID0gcmV0dXJuVHlwZVN0cmlwcGVkLnRyaW1taW5nQ2hhcmFjdGVycyhpbjogQ2hhcmFjdGVyU2V0KGNoYXJhY3RlcnNJbjogIiAiKSkKICAgICAgICByZXR1cm4gIlwodW5pcXVlTmFtZSktPlwocmV0dXJuVHlwZVN0cmlwcGVkKSIKICAgIH0KICAgIHByaXZhdGUgdmFyIG5hbWVTdWZmaXg6IFN0cmluZyB7CiAgICAgICAgZ3VhcmQgbGV0IGNvdW50ID0gTWV0aG9kV3JhcHBlci5yZWdpc3RlcmVkW3JlZ2lzdHJhdGlvbk5hbWVdIGVsc2UgeyByZXR1cm4gIiIgfQogICAgICAgIGd1YXJkIGNvdW50ID4gMSBlbHNlIHsgcmV0dXJuICIiIH0KICAgICAgICBndWFyZCBsZXQgaW5kZXggPSBNZXRob2RXcmFwcGVyLnN1ZmZpeGVzW3VuaXF1ZU5hbWVXaXRoUmV0dXJuVHlwZV0gZWxzZSB7IHJldHVybiAiIiB9CiAgICAgICAgcmV0dXJuICJfXChpbmRleCkiCiAgICB9CiAgICBwcml2YXRlIHZhciBtZXRob2RBdHRyaWJ1dGVzOiBTdHJpbmcgewogICAgICAgIHJldHVybiBIZWxwZXJzLmV4dHJhY3RBdHRyaWJ1dGVzKGZyb206IHNlbGYubWV0aG9kLmF0dHJpYnV0ZXMsIGZpbHRlck91dFN0YXJ0aW5nV2l0aDogWyJtdXRhdGluZyIsICJAaW5saW5hYmxlIl0pCiAgICB9CiAgICBwcml2YXRlIHZhciBtZXRob2RBdHRyaWJ1dGVzTm9uT2JqYzogU3RyaW5nIHsKICAgICAgICByZXR1cm4gSGVscGVycy5leHRyYWN0QXR0cmlidXRlcyhmcm9tOiBzZWxmLm1ldGhvZC5hdHRyaWJ1dGVzLCBmaWx0ZXJPdXRTdGFydGluZ1dpdGg6IFsibXV0YXRpbmciLCAiQGlubGluYWJsZSIsICJAb2JqYyJdKQogICAgfQoKICAgIHZhciBwcm90b3R5cGU6IFN0cmluZyB7CiAgICAgICAgcmV0dXJuICJcKHJlZ2lzdHJhdGlvbk5hbWUpXChuYW1lU3VmZml4KSIucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICJgIiwgd2l0aDogIiIpCiAgICB9CiAgICB2YXIgcGFyYW1ldGVyczogW1BhcmFtZXRlcldyYXBwZXJdIHsKICAgICAgICByZXR1cm4gZmlsdGVyZWRQYXJhbWV0ZXJzLm1hcCB7IFBhcmFtZXRlcldyYXBwZXIoJDAsIHNlbGYuZ2V0VmFyaWFkaWNQYXJhbWV0ZXJzTmFtZXMoKSkgfQogICAgfQogICAgdmFyIGZpbHRlcmVkUGFyYW1ldGVyczogW01ldGhvZFBhcmFtZXRlcl0gewogICAgICAgIHJldHVybiBtZXRob2QucGFyYW1ldGVycy5maWx0ZXIgeyAkMC5uYW1lICE9ICIiIH0KICAgIH0KICAgIHZhciBmdW5jdGlvblByb3RvdHlwZTogU3RyaW5nIHsKICAgICAgICBsZXQgdGhyb3dpbmc6IFN0cmluZyA9IHsKICAgICAgICAgICAgaWYgbWV0aG9kLnRocm93cyB7CiAgICAgICAgICAgICAgICByZXR1cm4gInRocm93cyAiCiAgICAgICAgICAgIH0gZWxzZSBpZiBtZXRob2QucmV0aHJvd3MgewogICAgICAgICAgICAgICAgcmV0dXJuICJyZXRocm93cyAiCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gIiIKICAgICAgICAgICAgfQogICAgICAgIH0oKQoKICAgICAgICBsZXQgc3RhdGljTW9kaWZpZXI6IFN0cmluZyA9ICJcKGFjY2Vzc01vZGlmaWVyKSAiCiAgICAgICAgbGV0IHBhcmFtcyA9IHJlcGxhY2luZ1NlbGYocGFyYW1ldGVyc0ZvclN0dWJTaWduYXR1cmUoKSkKICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHNlbGYubWV0aG9kQXR0cmlidXRlcwogICAgICAgIGF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzLmlzRW1wdHkgPyAiIiA6ICJcKGF0dHJpYnV0ZXMpXG5cdCIKICAgICAgICB2YXIgYXN5bmNNb2RpZmllciA9IHNlbGYuaXNBc3luYyA/ICJhc3luYyAiIDogIiIKCiAgICAgICAgaWYgbWV0aG9kLmlzSW5pdGlhbGl6ZXIgewogICAgICAgICAgICByZXR1cm4gIlwoYXR0cmlidXRlcylwdWJsaWMgcmVxdWlyZWQgXChtZXRob2QubmFtZSkgXChhc3luY01vZGlmaWVyKVwodGhyb3dpbmcpIgogICAgICAgIH0gZWxzZSBpZiBtZXRob2QucmV0dXJuVHlwZU5hbWUuaXNWb2lkIHsKICAgICAgICAgICAgbGV0IHdoZXJlUGFydElmTmVlZGVkOiBTdHJpbmcgPSB7CiAgICAgICAgICAgICAgICBpZiBtZXRob2QucmV0dXJuVHlwZU5hbWUubmFtZS5oYXNQcmVmaXgoIlZvaWQiKSB7CiAgICAgICAgICAgICAgICAgICAgbGV0IHJhbmdlID0gbWV0aG9kLnJldHVyblR5cGVOYW1lLm5hbWUucmFuZ2Uob2Y6ICJWb2lkIikhCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJcKG1ldGhvZC5yZXR1cm5UeXBlTmFtZS5uYW1lW3JhbmdlLnVwcGVyQm91bmQuLi5dKSIKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICFtZXRob2QucmV0dXJuVHlwZU5hbWUubmFtZS5pc0VtcHR5ID8gIlwobWV0aG9kLnJldHVyblR5cGVOYW1lLm5hbWUpICIgOiAiIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KCkKICAgICAgICAgICAgcmV0dXJuICJcKGF0dHJpYnV0ZXMpXChzdGF0aWNNb2RpZmllcilmdW5jIFwobWV0aG9kLnNob3J0TmFtZSlcKHBhcmFtcykgXChhc3luY01vZGlmaWVyKVwodGhyb3dpbmcpXCh3aGVyZVBhcnRJZk5lZWRlZCkiCiAgICAgICAgfSBlbHNlIGlmIHJldHVybnNHZW5lcmljQ29uc3RyYWluZWRUb1NlbGYgewogICAgICAgICAgICByZXR1cm4gIlwoYXR0cmlidXRlcylcKHN0YXRpY01vZGlmaWVyKWZ1bmMgXChtZXRob2Quc2hvcnROYW1lKVwocGFyYW1zKSBcKGFzeW5jTW9kaWZpZXIpXCh0aHJvd2luZyktPiBcKHJldHVyblR5cGVSZXBsYWNpbmdTZWxmKSAiCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuICJcKGF0dHJpYnV0ZXMpXChzdGF0aWNNb2RpZmllcilmdW5jIFwobWV0aG9kLnNob3J0TmFtZSlcKHBhcmFtcykgXChhc3luY01vZGlmaWVyKVwodGhyb3dpbmcpLT4gXChtZXRob2QucmV0dXJuVHlwZU5hbWUubmFtZSkgIgogICAgICAgIH0KICAgIH0KICAgIHZhciBpbnZvY2F0aW9uOiBTdHJpbmcgewogICAgICAgIGd1YXJkICFtZXRob2QuaXNJbml0aWFsaXplciBlbHNlIHsgcmV0dXJuICIiIH0KICAgICAgICBpZiBmaWx0ZXJlZFBhcmFtZXRlcnMuaXNFbXB0eSB7CiAgICAgICAgICAgIHJldHVybiAiYWRkSW52b2NhdGlvbiguXChwcm90b3R5cGUpKSIKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gImFkZEludm9jYXRpb24oLlwocHJvdG90eXBlKShcKHBhcmFtZXRlcnNGb3JNZXRob2RDYWxsKCkpKSkiCiAgICAgICAgfQogICAgfQogICAgdmFyIGdpdmVuVmFsdWU6IFN0cmluZyB7CiAgICAgICAgZ3VhcmQgIW1ldGhvZC5pc0luaXRpYWxpemVyIGVsc2UgeyByZXR1cm4gIiIgfQogICAgICAgIGd1YXJkIG1ldGhvZC50aHJvd3MgfHwgIW1ldGhvZC5yZXR1cm5UeXBlTmFtZS5pc1ZvaWQgZWxzZSB7IHJldHVybiAiIiB9CgogICAgICAgIGxldCBtZXRob2RUeXBlID0gZmlsdGVyZWRQYXJhbWV0ZXJzLmlzRW1wdHkgPyAiLlwocHJvdG90eXBlKSIgOiAiLlwocHJvdG90eXBlKShcKHBhcmFtZXRlcnNGb3JNZXRob2RDYWxsKCkpKSIKICAgICAgICBsZXQgcmV0dXJuVHlwZTogU3RyaW5nID0gcmV0dXJuc1NlbGYgPyAiX19TZWxmX18iIDogIlwoVHlwZVdyYXBwZXIobWV0aG9kLnJldHVyblR5cGVOYW1lKS5zdHJpcHBlZCkiCgogICAgICAgIGlmIG1ldGhvZC5yZXR1cm5UeXBlTmFtZS5pc1ZvaWQgewogICAgICAgICAgICByZXR1cm4gIiIiCiAgICAgICAgICAgIFxuXHRcdGRvIHsKICAgICAgICAgICAgXHRcdCAgICBfID0gdHJ5IG1ldGhvZFJldHVyblZhbHVlKFwobWV0aG9kVHlwZSkpLmNhc3RlZCgpIGFzIFZvaWQKICAgICAgICAgICAgXHRcdH1cKCIgIikKICAgICAgICAgICAgIiIiCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbGV0IGRlZmF1bHRWYWx1ZSA9IG1ldGhvZC5yZXR1cm5UeXBlTmFtZS5pc09wdGlvbmFsID8gIiA9IG5pbCIgOiAiIgogICAgICAgICAgICByZXR1cm4gIiIiCiAgICAgICAgICAgIFxuXHRcdHZhciBfX3ZhbHVlOiBcKHJldHVyblR5cGUpXChkZWZhdWx0VmFsdWUpCiAgICAgICAgICAgIFx0XHRkbyB7CiAgICAgICAgICAgIFx0XHQgICAgX192YWx1ZSA9IHRyeSBtZXRob2RSZXR1cm5WYWx1ZShcKG1ldGhvZFR5cGUpKS5jYXN0ZWQoKQogICAgICAgICAgICBcdFx0fVwoIiAiKQogICAgICAgICAgICAiIiIKICAgICAgICB9CiAgICB9CiAgICB2YXIgdGhyb3dWYWx1ZTogU3RyaW5nIHsKICAgICAgICBndWFyZCAhbWV0aG9kLmlzSW5pdGlhbGl6ZXIgZWxzZSB7IHJldHVybiAiIiB9CiAgICAgICAgZ3VhcmQgbWV0aG9kLnRocm93cyB8fCAhbWV0aG9kLnJldHVyblR5cGVOYW1lLmlzVm9pZCBlbHNlIHsgcmV0dXJuICIiIH0KICAgICAgICBsZXQgc2FmZUZhaWx1cmUgPSBtZXRob2QuaXNTdGF0aWMgPyAiIiA6ICJcdFx0XHRvbkZhdGFsRmFpbHVyZShcIlwobm9TdHViRGVmaW5lZE1lc3NhZ2UpXCIpXG4iCiAgICAgICAgLy8gRm9yIFZvaWQgYW5kIFJldHVybmluZyBvcHRpb25hbHMgLSB3ZSBhbGxvdyBub3Qgc3R1YmJlZCBjYXNlIHRvIGhhcHBlbiwgYXMgd2UgYXJlIHN0aWxsIGFibGUgdG8gcmV0dXJuCiAgICAgICAgbGV0IG5vU3R1YkhhbmRsaW5nID0gbWV0aG9kLnJldHVyblR5cGVOYW1lLmlzVm9pZCB8fCBtZXRob2QucmV0dXJuVHlwZU5hbWUuaXNPcHRpb25hbCA/ICJcdFx0XHQvLyBkbyBub3RoaW5nIiA6ICJcKHNhZmVGYWlsdXJlKVx0XHRcdEZhaWx1cmUoXCJcKG5vU3R1YkRlZmluZWRNZXNzYWdlKVwiKSIKICAgICAgICBndWFyZCBtZXRob2QudGhyb3dzIGVsc2UgewogICAgICAgICAgICByZXR1cm4gIiIiCiAgICAgICAgICAgIGNhdGNoIHsKICAgICAgICAgICAgXChub1N0dWJIYW5kbGluZykKICAgICAgICAgICAgXHRcdH0KICAgICAgICAgICAgIiIiCiAgICAgICAgfQoKICAgICAgICByZXR1cm4gIiIiCiAgICAgICAgY2F0Y2ggTW9ja0Vycm9yLm5vdFN0dWJlZCB7CiAgICAgICAgXChub1N0dWJIYW5kbGluZykKICAgICAgICBcdFx0fSBjYXRjaCB7CiAgICAgICAgXHRcdCAgICB0aHJvdyBlcnJvcgogICAgICAgIFx0XHR9CiAgICAgICAgIiIiCiAgICB9CiAgICB2YXIgcmV0dXJuVmFsdWU6IFN0cmluZyB7CiAgICAgICAgZ3VhcmQgIW1ldGhvZC5pc0luaXRpYWxpemVyIGVsc2UgeyByZXR1cm4gIiIgfQogICAgICAgIGd1YXJkICFtZXRob2QucmV0dXJuVHlwZU5hbWUuaXNWb2lkIGVsc2UgeyByZXR1cm4gIiIgfQoKICAgICAgICByZXR1cm4gIlxuXHRcdHJldHVybiBfX3ZhbHVlIgogICAgfQogICAgdmFyIGVxdWFsQ2FzZTogU3RyaW5nIHsKICAgICAgICBndWFyZCAhbWV0aG9kLmlzSW5pdGlhbGl6ZXIgZWxzZSB7IHJldHVybiAiIiB9CgogICAgICAgIGlmIGZpbHRlcmVkUGFyYW1ldGVycy5pc0VtcHR5IHsKICAgICAgICAgICAgcmV0dXJuICJjYXNlICguXChwcm90b3R5cGUpLCAuXChwcm90b3R5cGUpKToiCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbGV0IGxoc1BhcmFtcyA9IGZpbHRlcmVkUGFyYW1ldGVycy5tYXAgeyAibGV0IGxoc1woJDAubmFtZS5jYXBpdGFsaXplZCkiIH0uam9pbmVkKHNlcGFyYXRvcjogIiwgIikKICAgICAgICAgICAgbGV0IHJoc1BhcmFtcyA9IGZpbHRlcmVkUGFyYW1ldGVycy5tYXAgeyAibGV0IHJoc1woJDAubmFtZS5jYXBpdGFsaXplZCkiIH0uam9pbmVkKHNlcGFyYXRvcjogIiwgIikKICAgICAgICAgICAgcmV0dXJuICJjYXNlICguXChwcm90b3R5cGUpKFwobGhzUGFyYW1zKSksIC5cKHByb3RvdHlwZSkoXChyaHNQYXJhbXMpKSk6IgogICAgICAgIH0KICAgIH0KICAgIGZ1bmMgZXF1YWxDYXNlcygpIC0+IFN0cmluZyB7CiAgICAgICAgdmFyIHJlc3VsdHMgPSBzZWxmLmVxdWFsQ2FzZQoKICAgICAgICBndWFyZCAhcGFyYW1ldGVycy5pc0VtcHR5IGVsc2UgewogICAgICAgICAgICByZXN1bHRzICs9ICIgcmV0dXJuIC5tYXRjaCIKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdHMKICAgICAgICB9CgogICAgICAgIHJlc3VsdHMgKz0gIlxuXHRcdFx0XHR2YXIgcmVzdWx0czogW01hdGNoZXIuUGFyYW1ldGVyQ29tcGFyaXNvblJlc3VsdF0gPSBbXVxuIgogICAgICAgIHJlc3VsdHMgKz0gcGFyYW1ldGVycy5tYXAgeyAiXHRcdFx0XHRcKCQwLmNvbXBhcmF0b3JSZXN1bHQoKSkiIH0uam9pbmVkKHNlcGFyYXRvcjogIlxuIikKICAgICAgICByZXN1bHRzICs9ICJcblx0XHRcdFx0cmV0dXJuIE1hdGNoZXIuQ29tcGFyaXNvblJlc3VsdChyZXN1bHRzKSIKICAgICAgICByZXR1cm4gcmVzdWx0cwogICAgfQogICAgdmFyIGludFZhbHVlQ2FzZTogU3RyaW5nIHsKICAgICAgICBpZiBmaWx0ZXJlZFBhcmFtZXRlcnMuaXNFbXB0eSB7CiAgICAgICAgICAgIHJldHVybiAiY2FzZSAuXChwcm90b3R5cGUpOiByZXR1cm4gMCIKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBsZXQgcGFyYW1zID0gZmlsdGVyZWRQYXJhbWV0ZXJzLmVudW1lcmF0ZWQoKS5tYXAgeyBvZmZzZXQsIF8gaW4KICAgICAgICAgICAgICAgIHJldHVybiAicFwob2Zmc2V0KSIKICAgICAgICAgICAgfQogICAgICAgICAgICBsZXQgZGVmaW5pdGlvbnMgPSBwYXJhbXMuam9pbmVkKHNlcGFyYXRvcjogIiwgIikKICAgICAgICAgICAgbGV0IHBhcmFtc1N1bSA9IHBhcmFtcy5tYXAoeyAiXCgkMCkuaW50VmFsdWUiIH0pLmpvaW5lZChzZXBhcmF0b3I6ICIgKyAiKQogICAgICAgICAgICByZXR1cm4gImNhc2UgbGV0IC5cKHByb3RvdHlwZSkoXChkZWZpbml0aW9ucykpOiByZXR1cm4gXChwYXJhbXNTdW0pIgogICAgICAgIH0KICAgIH0KICAgIHZhciBhc3NlcnRpb25OYW1lOiBTdHJpbmcgewogICAgICAgIHJldHVybiAiY2FzZSAuXChwcm90b3R5cGUpOiByZXR1cm4gXCIuXChtZXRob2Quc2VsZWN0b3JOYW1lKVwobWV0aG9kLnBhcmFtZXRlcnMuaXNFbXB0eSA/ICIoKSIgOiAiIilcIiIKICAgIH0KCiAgICB2YXIgcmV0dXJuc1NlbGY6IEJvb2wgewogICAgICAgIGd1YXJkICFyZXR1cm5zR2VuZXJpY0NvbnN0cmFpbmVkVG9TZWxmIGVsc2UgeyByZXR1cm4gdHJ1ZSB9CiAgICAgICAgcmV0dXJuICFtZXRob2QucmV0dXJuVHlwZU5hbWUuaXNWb2lkICYmIFR5cGVXcmFwcGVyKG1ldGhvZC5yZXR1cm5UeXBlTmFtZSkuaXNTZWxmVHlwZQogICAgfQogICAgdmFyIHJldHVybnNHZW5lcmljQ29uc3RyYWluZWRUb1NlbGY6IEJvb2wgewogICAgICAgIGxldCBkZWZhdWx0UmV0dXJuVHlwZSA9ICJcKG1ldGhvZC5yZXR1cm5UeXBlTmFtZS5uYW1lKSAiCiAgICAgICAgcmV0dXJuIGRlZmF1bHRSZXR1cm5UeXBlICE9IHJldHVyblR5cGVSZXBsYWNpbmdTZWxmCiAgICB9CiAgICB2YXIgcmV0dXJuVHlwZVJlcGxhY2luZ1NlbGY6IFN0cmluZyB7CiAgICAgICAgcmV0dXJuIHJlcGxhY2luZ1NlbGYoIlwobWV0aG9kLnJldHVyblR5cGVOYW1lLm5hbWUpICIpCiAgICB9CiAgICB2YXIgcGFyYW1ldGVyc0NvbnRhaW5zU2VsZjogQm9vbCB7CiAgICAgICAgcmV0dXJuIHJlcGxhY2luZ1NlbGYocGFyYW1ldGVyc0ZvclN0dWJTaWduYXR1cmUoKSkgIT0gcGFyYW1ldGVyc0ZvclN0dWJTaWduYXR1cmUoKQogICAgfQoKICAgIHZhciByZXBsYWNlU2VsZjogU3RyaW5nIHsKICAgICAgICByZXR1cm4gQ3VycmVudC5zZWxmVHlwZQogICAgfQoKICAgIGluaXQoXyBtZXRob2Q6IFNvdXJjZXJ5UnVudGltZS5NZXRob2QpIHsKICAgICAgICBzZWxmLm1ldGhvZCA9IG1ldGhvZAogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZnVuYyBjbGVhcigpIC0+IFN0cmluZyB7CiAgICAgICAgTWV0aG9kV3JhcHBlci5yZWdpc3RlcmVkID0gWzpdCiAgICAgICAgTWV0aG9kV3JhcHBlci5zdWZmaXhlcyA9IFs6XQogICAgICAgIE1ldGhvZFdyYXBwZXIuc3VmZml4ZXNXaXRob3V0UmV0dXJuVHlwZSA9IFs6XQogICAgICAgIHJldHVybiAiIgogICAgfQoKICAgIGZ1bmMgcmVnaXN0ZXIoKSB7CiAgICAgICAgTWV0aG9kV3JhcHBlci5yZWdpc3RlcihyZWdpc3RyYXRpb25OYW1lLHVuaXF1ZU5hbWUsdW5pcXVlTmFtZVdpdGhSZXR1cm5UeXBlKQogICAgfQoKICAgIHN0YXRpYyBmdW5jIHJlZ2lzdGVyKF8gbmFtZTogU3RyaW5nLCBfIHVuaXF1ZU5hbWU6IFN0cmluZywgXyB1bmlxdWVOYW1lV2l0aFJldHVyblR5cGU6IFN0cmluZykgewogICAgICAgIGlmIGxldCBjb3VudCA9IE1ldGhvZFdyYXBwZXIucmVnaXN0ZXJlZFtuYW1lXSB7CiAgICAgICAgICAgIE1ldGhvZFdyYXBwZXIucmVnaXN0ZXJlZFtuYW1lXSA9IGNvdW50ICsgMQogICAgICAgICAgICBNZXRob2RXcmFwcGVyLnN1ZmZpeGVzW3VuaXF1ZU5hbWVXaXRoUmV0dXJuVHlwZV0gPSBjb3VudCArIDEKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBNZXRob2RXcmFwcGVyLnJlZ2lzdGVyZWRbbmFtZV0gPSAxCiAgICAgICAgICAgIE1ldGhvZFdyYXBwZXIuc3VmZml4ZXNbdW5pcXVlTmFtZVdpdGhSZXR1cm5UeXBlXSA9IDEKICAgICAgICB9CgogICAgICAgIGlmIGxldCBjb3VudCA9IE1ldGhvZFdyYXBwZXIuc3VmZml4ZXNXaXRob3V0UmV0dXJuVHlwZVt1bmlxdWVOYW1lXSB7CiAgICAgICAgICAgIE1ldGhvZFdyYXBwZXIuc3VmZml4ZXNXaXRob3V0UmV0dXJuVHlwZVt1bmlxdWVOYW1lXSA9IGNvdW50ICsgMQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIE1ldGhvZFdyYXBwZXIuc3VmZml4ZXNXaXRob3V0UmV0dXJuVHlwZVt1bmlxdWVOYW1lXSA9IDEKICAgICAgICB9CiAgICB9CgogICAgZnVuYyByZXR1cm5UeXBlTWF0dGVycygpIC0+IEJvb2wgewogICAgICAgIGxldCBjb3VudCA9IE1ldGhvZFdyYXBwZXIuc3VmZml4ZXNXaXRob3V0UmV0dXJuVHlwZVt1bmlxdWVOYW1lXSA/PyAwCiAgICAgICAgcmV0dXJuIGNvdW50ID4gMQogICAgfQoKICAgIGZ1bmMgd3JhcHBlZEluTWV0aG9kVHlwZSgpIC0+IEJvb2wgewogICAgICAgIHJldHVybiAhbWV0aG9kLmlzSW5pdGlhbGl6ZXIKICAgIH0KCiAgICBmdW5jIHJldHVybmluZ1BhcmFtZXRlcihfIG11bHRpcGxlOiBCb29sLCBfIGZyb250OiBCb29sKSAtPiBTdHJpbmcgewogICAgICAgIGd1YXJkIHJldHVyblR5cGVNYXR0ZXJzKCkgZWxzZSB7IHJldHVybiAiIiB9CiAgICAgICAgbGV0IHJldHVybmluZzogU3RyaW5nID0gInJldHVybmluZzogXChyZXR1cm5UeXBlU3RyaXBwZWQobWV0aG9kLCB0eXBlOiB0cnVlKSkiCiAgICAgICAgZ3VhcmQgbXVsdGlwbGUgZWxzZSB7IHJldHVybiByZXR1cm5pbmcgfQoKICAgICAgICByZXR1cm4gZnJvbnQgPyAiLCBcKHJldHVybmluZykiIDogIlwocmV0dXJuaW5nKSwgIgogICAgfQoKICAgIC8vIFN0dWIKICAgIGZ1bmMgc3R1YkJvZHkoKSAtPiBTdHJpbmcgewogICAgICAgIGxldCBib2R5OiBTdHJpbmcgPSB7CiAgICAgICAgICAgIGlmIG1ldGhvZC5pc0luaXRpYWxpemVyIHx8ICFyZXR1cm5zU2VsZiB7CiAgICAgICAgICAgICAgICByZXR1cm4gaW52b2NhdGlvbiArIHBlcmZvcm1DYWxsKCkgKyBnaXZlblZhbHVlICsgdGhyb3dWYWx1ZSArIHJldHVyblZhbHVlCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gd3JhcHBlZFN0dWJQcmVmaXgoKQogICAgICAgICAgICAgICAgICAgICsgIlx0XHQiICsgaW52b2NhdGlvbgogICAgICAgICAgICAgICAgICAgICsgcGVyZm9ybUNhbGwoKQogICAgICAgICAgICAgICAgICAgICsgZ2l2ZW5WYWx1ZQogICAgICAgICAgICAgICAgICAgICsgdGhyb3dWYWx1ZQogICAgICAgICAgICAgICAgICAgICsgcmV0dXJuVmFsdWUKICAgICAgICAgICAgICAgICAgICArIHdyYXBwZWRTdHViUG9zdGZpeCgpCiAgICAgICAgICAgIH0KICAgICAgICB9KCkKICAgICAgICByZXR1cm4gcmVwbGFjaW5nU2VsZihib2R5KQogICAgfQoKICAgIGZ1bmMgd3JhcHBlZFN0dWJQcmVmaXgoKSAtPiBTdHJpbmcgewogICAgICAgIGd1YXJkICFtZXRob2QuaXNJbml0aWFsaXplciwgcmV0dXJuc1NlbGYgZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAiIgogICAgICAgIH0KCiAgICAgICAgbGV0IHRocm93aW5nOiBTdHJpbmcgPSB7CiAgICAgICAgICAgIGlmIG1ldGhvZC50aHJvd3MgewogICAgICAgICAgICAgICAgcmV0dXJuICJ0aHJvd3MgIgogICAgICAgICAgICB9IGVsc2UgaWYgbWV0aG9kLnJldGhyb3dzIHsKICAgICAgICAgICAgICAgIHJldHVybiAicmV0aHJvd3MgIgogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuICIiCiAgICAgICAgICAgIH0KICAgICAgICB9KCkKCiAgICAgICAgcmV0dXJuICJmdW5jIF93cmFwcGVkPF9fU2VsZl9fPigpIFwodGhyb3dpbmcpLT4gX19TZWxmX18ge1xuIgogICAgfQoKICAgIGZ1bmMgd3JhcHBlZFN0dWJQb3N0Zml4KCkgLT4gU3RyaW5nIHsKICAgICAgICBndWFyZCAhbWV0aG9kLmlzSW5pdGlhbGl6ZXIsIHJldHVybnNTZWxmIGVsc2UgewogICAgICAgICAgICByZXR1cm4gIiIKICAgICAgICB9CgogICAgICAgIGxldCB0aHJvd2luZzogU3RyaW5nID0gKG1ldGhvZC50aHJvd3MgfHwgbWV0aG9kLnJldGhyb3dzKSA/ICJ0cnkgIjogIiIKCiAgICAgICAgcmV0dXJuICJcblx0XHR9IgogICAgICAgICAgICArICJcblx0XHRyZXR1cm4gXCh0aHJvd2luZylfd3JhcHBlZCgpIgogICAgfQoKICAgIC8vIE1ldGhvZCBUeXBlCiAgICBmdW5jIG1ldGhvZFR5cGVEZWNsYXJhdGlvbldpdGhQYXJhbWV0ZXJzKCkgLT4gU3RyaW5nIHsKICAgICAgICBpZiBmaWx0ZXJlZFBhcmFtZXRlcnMuaXNFbXB0eSB7CiAgICAgICAgICAgIHJldHVybiAiY2FzZSBcKHByb3RvdHlwZSkiCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuICJjYXNlIFwocHJvdG90eXBlKShcKHBhcmFtZXRlcnNGb3JNZXRob2RUeXBlRGVjbGFyYXRpb24oYXZhaWxhYmlsaXR5OiBoYXNBdmFpbGFiaWxpdHkpKSkiCiAgICAgICAgfQogICAgfQoKICAgIC8vIEdpdmVuCiAgICBmdW5jIGNvbnRhaW5zRW1wdHlBcmd1bWVudExhYmVscygpIC0+IEJvb2wgewogICAgICAgIHJldHVybiBwYXJhbWV0ZXJzLmNvbnRhaW5zKHdoZXJlOiB7ICQwLnBhcmFtZXRlci5hcmd1bWVudExhYmVsID09IG5pbCB9KQogICAgfQoKICAgIGZ1bmMgZ2l2ZW5SZXR1cm5UeXBlU3RyaW5nKCkgLT4gU3RyaW5nIHsKICAgICAgICBsZXQgcmV0dXJuVHlwZVN0cmluZzogU3RyaW5nID0gewogICAgICAgICAgICBndWFyZCAhcmV0dXJuc0dlbmVyaWNDb25zdHJhaW5lZFRvU2VsZiBlbHNlIHsgcmV0dXJuIHJldHVyblR5cGVSZXBsYWNpbmdTZWxmIH0KICAgICAgICAgICAgZ3VhcmQgIXJldHVybnNTZWxmIGVsc2UgeyByZXR1cm4gcmVwbGFjZVNlbGYgfQogICAgICAgICAgICByZXR1cm4gVHlwZVdyYXBwZXIobWV0aG9kLnJldHVyblR5cGVOYW1lKS5zdHJpcHBlZAogICAgICAgIH0oKQogICAgICAgIHJldHVybiByZXR1cm5UeXBlU3RyaW5nCiAgICB9CgogICAgZnVuYyBnaXZlbkNvbnN0cnVjdG9yTmFtZShwcmVmaXg6IFN0cmluZyA9ICIiKSAtPiBTdHJpbmcgewogICAgICAgIGxldCByZXR1cm5UeXBlU3RyaW5nID0gZ2l2ZW5SZXR1cm5UeXBlU3RyaW5nKCkKICAgICAgICBsZXQgKGFubm90YXRpb24sIF8sIF8pID0gbWV0aG9kSW5mbygpCiAgICAgICAgbGV0IGNsYXVzZUNvbnN0cmFpbnRzID0gd2hlcmVDbGF1c2VFeHByZXNzaW9uKCkKCiAgICAgICAgaWYgZmlsdGVyZWRQYXJhbWV0ZXJzLmlzRW1wdHkgewogICAgICAgICAgICByZXR1cm4gIlwoYW5ub3RhdGlvbilwdWJsaWMgc3RhdGljIGZ1bmMgXChtZXRob2Quc2hvcnROYW1lKSh3aWxsUmV0dXJuOiBcKHJldHVyblR5cGVTdHJpbmcpLi4uKSAtPiBcKHByZWZpeClNZXRob2RTdHViIiArIGNsYXVzZUNvbnN0cmFpbnRzCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuICJcKGFubm90YXRpb24pcHVibGljIHN0YXRpYyBmdW5jIFwobWV0aG9kLnNob3J0TmFtZSkoXChwYXJhbWV0ZXJzRm9yUHJveHlTaWduYXR1cmUoKSksIHdpbGxSZXR1cm46IFwocmV0dXJuVHlwZVN0cmluZykuLi4pIC0+IFwocHJlZml4KU1ldGhvZFN0dWIiICsgY2xhdXNlQ29uc3RyYWludHMKICAgICAgICB9CiAgICB9CgogICAgZnVuYyBnaXZlbkNvbnN0cnVjdG9yTmFtZVRocm93cyhwcmVmaXg6IFN0cmluZyA9ICIiKSAtPiBTdHJpbmcgewogICAgICAgIGxldCAoYW5ub3RhdGlvbiwgXywgXykgPSBtZXRob2RJbmZvKCkKICAgICAgICBsZXQgY2xhdXNlQ29uc3RyYWludHMgPSB3aGVyZUNsYXVzZUV4cHJlc3Npb24oKQoKICAgICAgICBsZXQgZ2VuZXJpY3NBcnJheSA9IGdldEdlbmVyaWNzQ29uc3RyYWludHMoZ2V0R2VuZXJpY3NBbW9uZ1BhcmFtZXRlcnMoKSwgZmlsdGVyU2luZ2xlOiBmYWxzZSkKICAgICAgICBsZXQgZ2VuZXJpY3MgPSBnZW5lcmljc0FycmF5LmlzRW1wdHkgPyAiIiA6ICI8XChnZW5lcmljc0FycmF5LmpvaW5lZChzZXBhcmF0b3I6ICIsICIpKT4iCgogICAgICAgIGlmIGZpbHRlcmVkUGFyYW1ldGVycy5pc0VtcHR5IHsKICAgICAgICAgICAgcmV0dXJuICJcKGFubm90YXRpb24pcHVibGljIHN0YXRpYyBmdW5jIFwobWV0aG9kLmNhbGxOYW1lKVwoZ2VuZXJpY3MpKHdpbGxUaHJvdzogRXJyb3IuLi4pIC0+IFwocHJlZml4KU1ldGhvZFN0dWIiICsgY2xhdXNlQ29uc3RyYWludHMKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gIlwoYW5ub3RhdGlvbilwdWJsaWMgc3RhdGljIGZ1bmMgXChtZXRob2QuY2FsbE5hbWUpXChnZW5lcmljcykoXChwYXJhbWV0ZXJzRm9yUHJveHlTaWduYXR1cmUoKSksIHdpbGxUaHJvdzogRXJyb3IuLi4pIC0+IFwocHJlZml4KU1ldGhvZFN0dWIiICsgY2xhdXNlQ29uc3RyYWludHMKICAgICAgICB9CiAgICB9CgogICAgZnVuYyBnaXZlbkNvbnN0cnVjdG9yKHByZWZpeDogU3RyaW5nID0gIiIpIC0+IFN0cmluZyB7CiAgICAgICAgaWYgZmlsdGVyZWRQYXJhbWV0ZXJzLmlzRW1wdHkgewogICAgICAgICAgICByZXR1cm4gInJldHVybiBcKHByZWZpeClHaXZlbihtZXRob2Q6IC5cKHByb3RvdHlwZSksIHByb2R1Y3RzOiB3aWxsUmV0dXJuLm1hcCh7IFN0dWJQcm9kdWN0LnJldHVybigkMCBhcyBBbnkpIH0pKSIKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gInJldHVybiBcKHByZWZpeClHaXZlbihtZXRob2Q6IC5cKHByb3RvdHlwZSkoXChwYXJhbWV0ZXJzRm9yUHJveHlJbml0KCkpKSwgcHJvZHVjdHM6IHdpbGxSZXR1cm4ubWFwKHsgU3R1YlByb2R1Y3QucmV0dXJuKCQwIGFzIEFueSkgfSkpIgogICAgICAgIH0KICAgIH0KCiAgICBmdW5jIGdpdmVuQ29uc3RydWN0b3JUaHJvd3MocHJlZml4OiBTdHJpbmcgPSAiIikgLT4gU3RyaW5nIHsKICAgICAgICBpZiBmaWx0ZXJlZFBhcmFtZXRlcnMuaXNFbXB0eSB7CiAgICAgICAgICAgIHJldHVybiAicmV0dXJuIFwocHJlZml4KUdpdmVuKG1ldGhvZDogLlwocHJvdG90eXBlKSwgcHJvZHVjdHM6IHdpbGxUaHJvdy5tYXAoeyBTdHViUHJvZHVjdC50aHJvdygkMCkgfSkpIgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAicmV0dXJuIFwocHJlZml4KUdpdmVuKG1ldGhvZDogLlwocHJvdG90eXBlKShcKHBhcmFtZXRlcnNGb3JQcm94eUluaXQoKSkpLCBwcm9kdWN0czogd2lsbFRocm93Lm1hcCh7IFN0dWJQcm9kdWN0LnRocm93KCQwKSB9KSkiCiAgICAgICAgfQogICAgfQoKICAgIC8vIEdpdmVuIHdpbGxQcm9kdWNlCiAgICBmdW5jIGdpdmVuUHJvZHVjZUNvbnN0cnVjdG9yTmFtZShwcmVmaXg6IFN0cmluZyA9ICIiKSAtPiBTdHJpbmcgewogICAgICAgIGxldCByZXR1cm5UeXBlU3RyaW5nID0gZ2l2ZW5SZXR1cm5UeXBlU3RyaW5nKCkKICAgICAgICBsZXQgKGFubm90YXRpb24sIF8sIF8pID0gbWV0aG9kSW5mbygpCiAgICAgICAgbGV0IHByb2R1Y2VDbG9zdXJlID0gIihTdHViYmVyPFwocmV0dXJuVHlwZVN0cmluZyk+KSAtPiBWb2lkIgogICAgICAgIGxldCBjbGF1c2VDb25zdHJhaW50cyA9IHdoZXJlQ2xhdXNlRXhwcmVzc2lvbigpCgogICAgICAgIGlmIGZpbHRlcmVkUGFyYW1ldGVycy5pc0VtcHR5IHsKICAgICAgICAgICAgcmV0dXJuICJcKGFubm90YXRpb24pcHVibGljIHN0YXRpYyBmdW5jIFwobWV0aG9kLnNob3J0TmFtZSkod2lsbFByb2R1Y2U6IFwocHJvZHVjZUNsb3N1cmUpKSAtPiBcKHByZWZpeClNZXRob2RTdHViIiArIGNsYXVzZUNvbnN0cmFpbnRzCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuICJcKGFubm90YXRpb24pcHVibGljIHN0YXRpYyBmdW5jIFwobWV0aG9kLnNob3J0TmFtZSkoXChwYXJhbWV0ZXJzRm9yUHJveHlTaWduYXR1cmUoKSksIHdpbGxQcm9kdWNlOiBcKHByb2R1Y2VDbG9zdXJlKSkgLT4gXChwcmVmaXgpTWV0aG9kU3R1YiIgKyBjbGF1c2VDb25zdHJhaW50cwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jIGdpdmVuUHJvZHVjZUNvbnN0cnVjdG9yTmFtZVRocm93cyhwcmVmaXg6IFN0cmluZyA9ICIiKSAtPiBTdHJpbmcgewogICAgICAgIGxldCByZXR1cm5UeXBlU3RyaW5nID0gZ2l2ZW5SZXR1cm5UeXBlU3RyaW5nKCkKICAgICAgICBsZXQgKGFubm90YXRpb24sIF8sIF8pID0gbWV0aG9kSW5mbygpCiAgICAgICAgbGV0IHByb2R1Y2VDbG9zdXJlID0gIihTdHViYmVyVGhyb3dzPFwocmV0dXJuVHlwZVN0cmluZyk+KSAtPiBWb2lkIgogICAgICAgIGxldCBjbGF1c2VDb25zdHJhaW50cyA9IHdoZXJlQ2xhdXNlRXhwcmVzc2lvbigpCgogICAgICAgIGlmIGZpbHRlcmVkUGFyYW1ldGVycy5pc0VtcHR5IHsKICAgICAgICAgICAgcmV0dXJuICJcKGFubm90YXRpb24pcHVibGljIHN0YXRpYyBmdW5jIFwobWV0aG9kLnNob3J0TmFtZSkod2lsbFByb2R1Y2U6IFwocHJvZHVjZUNsb3N1cmUpKSAtPiBcKHByZWZpeClNZXRob2RTdHViIiArIGNsYXVzZUNvbnN0cmFpbnRzCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuICJcKGFubm90YXRpb24pcHVibGljIHN0YXRpYyBmdW5jIFwobWV0aG9kLnNob3J0TmFtZSkoXChwYXJhbWV0ZXJzRm9yUHJveHlTaWduYXR1cmUoKSksIHdpbGxQcm9kdWNlOiBcKHByb2R1Y2VDbG9zdXJlKSkgLT4gXChwcmVmaXgpTWV0aG9kU3R1YiIgKyBjbGF1c2VDb25zdHJhaW50cwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jIGdpdmVuUHJvZHVjZUNvbnN0cnVjdG9yKHByZWZpeDogU3RyaW5nID0gIiIpIC0+IFN0cmluZyB7CiAgICAgICAgbGV0IHJldHVyblR5cGVTdHJpbmcgPSBnaXZlblJldHVyblR5cGVTdHJpbmcoKQogICAgICAgIHJldHVybiAiIiIKICAgICAgICBsZXQgd2lsbFJldHVybjogW1wocmV0dXJuVHlwZVN0cmluZyldID0gW10KICAgICAgICBcdFx0XHRsZXQgZ2l2ZW46IFwocHJlZml4KUdpdmVuID0geyBcKGdpdmVuQ29uc3RydWN0b3IocHJlZml4OiBwcmVmaXgpKSB9KCkKICAgICAgICBcdFx0XHRsZXQgc3R1YmJlciA9IGdpdmVuLnN0dWIoZm9yOiAoXChyZXR1cm5UeXBlU3RyaW5nKSkuc2VsZikKICAgICAgICBcdFx0XHR3aWxsUHJvZHVjZShzdHViYmVyKQogICAgICAgIFx0XHRcdHJldHVybiBnaXZlbgogICAgICAgICIiIgogICAgfQoKICAgIGZ1bmMgZ2l2ZW5Qcm9kdWNlQ29uc3RydWN0b3JUaHJvd3MocHJlZml4OiBTdHJpbmcgPSAiIikgLT4gU3RyaW5nIHsKICAgICAgICBsZXQgcmV0dXJuVHlwZVN0cmluZyA9IGdpdmVuUmV0dXJuVHlwZVN0cmluZygpCiAgICAgICAgcmV0dXJuICIiIgogICAgICAgIGxldCB3aWxsVGhyb3c6IFtFcnJvcl0gPSBbXQogICAgICAgIFx0XHRcdGxldCBnaXZlbjogXChwcmVmaXgpR2l2ZW4gPSB7IFwoZ2l2ZW5Db25zdHJ1Y3RvclRocm93cyhwcmVmaXg6IHByZWZpeCkpIH0oKQogICAgICAgIFx0XHRcdGxldCBzdHViYmVyID0gZ2l2ZW4uc3R1YlRocm93cyhmb3I6IChcKHJldHVyblR5cGVTdHJpbmcpKS5zZWxmKQogICAgICAgIFx0XHRcdHdpbGxQcm9kdWNlKHN0dWJiZXIpCiAgICAgICAgXHRcdFx0cmV0dXJuIGdpdmVuCiAgICAgICAgIiIiCiAgICB9CgogICAgLy8gVmVyaWZ5CiAgICBmdW5jIHZlcmlmaWNhdGlvblByb3h5Q29uc3RydWN0b3JOYW1lKHByZWZpeDogU3RyaW5nID0gIiIpIC0+IFN0cmluZyB7CiAgICAgICAgbGV0IChhbm5vdGF0aW9uLCBtZXRob2ROYW1lLCBnZW5lcmljQ29uc3RyYWlucykgPSBtZXRob2RJbmZvKCkKCiAgICAgICAgaWYgZmlsdGVyZWRQYXJhbWV0ZXJzLmlzRW1wdHkgewogICAgICAgICAgICByZXR1cm4gIlwoYW5ub3RhdGlvbilwdWJsaWMgc3RhdGljIGZ1bmMgXChtZXRob2ROYW1lKShcKHJldHVybmluZ1BhcmFtZXRlcihmYWxzZSx0cnVlKSkpIC0+IFwocHJlZml4KVZlcmlmeVwoZ2VuZXJpY0NvbnN0cmFpbnMpIgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAiXChhbm5vdGF0aW9uKXB1YmxpYyBzdGF0aWMgZnVuYyBcKG1ldGhvZE5hbWUpKFwocGFyYW1ldGVyc0ZvclByb3h5U2lnbmF0dXJlKCkpXChyZXR1cm5pbmdQYXJhbWV0ZXIodHJ1ZSx0cnVlKSkpIC0+IFwocHJlZml4KVZlcmlmeVwoZ2VuZXJpY0NvbnN0cmFpbnMpIgogICAgICAgIH0KICAgIH0KCiAgICBmdW5jIHZlcmlmaWNhdGlvblByb3h5Q29uc3RydWN0b3IocHJlZml4OiBTdHJpbmcgPSAiIikgLT4gU3RyaW5nIHsKICAgICAgICBpZiBmaWx0ZXJlZFBhcmFtZXRlcnMuaXNFbXB0eSB7CiAgICAgICAgICAgIHJldHVybiAicmV0dXJuIFwocHJlZml4KVZlcmlmeShtZXRob2Q6IC5cKHByb3RvdHlwZSkpIgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAicmV0dXJuIFwocHJlZml4KVZlcmlmeShtZXRob2Q6IC5cKHByb3RvdHlwZSkoXChwYXJhbWV0ZXJzRm9yUHJveHlJbml0KCkpKSkiCiAgICAgICAgfQogICAgfQoKICAgIC8vIFBlcmZvcm0KICAgIGZ1bmMgcGVyZm9ybVByb3h5Q29uc3RydWN0b3JOYW1lKHByZWZpeDogU3RyaW5nID0gIiIpIC0+IFN0cmluZyB7CiAgICAgICAgbGV0IGJvZHk6IFN0cmluZyA9IHsKICAgICAgICAgICAgbGV0IChhbm5vdGF0aW9uLCBtZXRob2ROYW1lLCBnZW5lcmljQ29uc3RyYWlucykgPSBtZXRob2RJbmZvKCkKCiAgICAgICAgICAgIGlmIGZpbHRlcmVkUGFyYW1ldGVycy5pc0VtcHR5IHsKICAgICAgICAgICAgICAgIHJldHVybiAiXChhbm5vdGF0aW9uKXB1YmxpYyBzdGF0aWMgZnVuYyBcKG1ldGhvZE5hbWUpKFwocmV0dXJuaW5nUGFyYW1ldGVyKHRydWUsZmFsc2UpKXBlcmZvcm06IEBlc2NhcGluZyBcKHBlcmZvcm1Qcm94eUNsb3N1cmVUeXBlKCkpKSAtPiBcKHByZWZpeClQZXJmb3JtXChnZW5lcmljQ29uc3RyYWlucykiCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gIlwoYW5ub3RhdGlvbilwdWJsaWMgc3RhdGljIGZ1bmMgXChtZXRob2ROYW1lKShcKHBhcmFtZXRlcnNGb3JQcm94eVNpZ25hdHVyZSgpKSwgXChyZXR1cm5pbmdQYXJhbWV0ZXIodHJ1ZSxmYWxzZSkpcGVyZm9ybTogQGVzY2FwaW5nIFwocGVyZm9ybVByb3h5Q2xvc3VyZVR5cGUoKSkpIC0+IFwocHJlZml4KVBlcmZvcm1cKGdlbmVyaWNDb25zdHJhaW5zKSIKICAgICAgICAgICAgfQogICAgICAgIH0oKQogICAgICAgIHJldHVybiByZXBsYWNpbmdTZWxmKGJvZHkpCiAgICB9CgogICAgZnVuYyBwZXJmb3JtUHJveHlDb25zdHJ1Y3RvcihwcmVmaXg6IFN0cmluZyA9ICIiKSAtPiBTdHJpbmcgewogICAgICAgIGlmIGZpbHRlcmVkUGFyYW1ldGVycy5pc0VtcHR5IHsKICAgICAgICAgICAgcmV0dXJuICJyZXR1cm4gXChwcmVmaXgpUGVyZm9ybShtZXRob2Q6IC5cKHByb3RvdHlwZSksIHBlcmZvcm1zOiBwZXJmb3JtKSIKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gInJldHVybiBcKHByZWZpeClQZXJmb3JtKG1ldGhvZDogLlwocHJvdG90eXBlKShcKHBhcmFtZXRlcnNGb3JQcm94eUluaXQoKSkpLCBwZXJmb3JtczogcGVyZm9ybSkiCiAgICAgICAgfQogICAgfQoKICAgIGZ1bmMgcGVyZm9ybVByb3h5Q2xvc3VyZVR5cGUoKSAtPiBTdHJpbmcgewogICAgICAgIGlmIGZpbHRlcmVkUGFyYW1ldGVycy5pc0VtcHR5IHsKICAgICAgICAgICAgcmV0dXJuICIoKSAtPiBWb2lkIgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGxldCBwYXJhbWV0ZXJzID0gc2VsZi5wYXJhbWV0ZXJzCiAgICAgICAgICAgICAgICAubWFwIHsgIlwoJDAuanVzdFBlcmZvcm1UeXBlKSIgfQogICAgICAgICAgICAgICAgLmpvaW5lZChzZXBhcmF0b3I6ICIsICIpCiAgICAgICAgICAgIHJldHVybiAiKFwocGFyYW1ldGVycykpIC0+IFZvaWQiCiAgICAgICAgfQogICAgfQoKICAgIGZ1bmMgcGVyZm9ybVByb3h5Q2xvc3VyZUNhbGwoKSAtPiBTdHJpbmcgewogICAgICAgIGlmIGZpbHRlcmVkUGFyYW1ldGVycy5pc0VtcHR5IHsKICAgICAgICAgICAgcmV0dXJuICJwZXJmb3JtPygpIgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGxldCBwYXJhbWV0ZXJzID0gZmlsdGVyZWRQYXJhbWV0ZXJzCiAgICAgICAgICAgICAgICAubWFwIHsgcCBpbgogICAgICAgICAgICAgICAgICAgIGxldCB3cmFwcGVkID0gUGFyYW1ldGVyV3JhcHBlcihwLCBzZWxmLmdldFZhcmlhZGljUGFyYW1ldGVyc05hbWVzKCkpCiAgICAgICAgICAgICAgICAgICAgbGV0IGlzQXV0b2xvc3VyZSA9IHdyYXBwZWQuanVzdFR5cGUuaGFzUHJlZml4KCJAYXV0b2Nsb3N1cmUiKQogICAgICAgICAgICAgICAgICAgIHJldHVybiAiXChwLmlub3V0ID8gIiYiIDogIiIpYFwocC5uYW1lKWBcKGlzQXV0b2xvc3VyZSA/ICIoKSIgOiAiIikiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAuam9pbmVkKHNlcGFyYXRvcjogIiwgIikKICAgICAgICAgICAgcmV0dXJuICJwZXJmb3JtPyhcKHBhcmFtZXRlcnMpKSIKICAgICAgICB9CiAgICB9CgogICAgZnVuYyBwZXJmb3JtQ2FsbCgpIC0+IFN0cmluZyB7CiAgICAgICAgZ3VhcmQgIW1ldGhvZC5pc0luaXRpYWxpemVyIGVsc2UgeyByZXR1cm4gIiIgfQogICAgICAgIGxldCB0eXBlID0gcGVyZm9ybVByb3h5Q2xvc3VyZVR5cGUoKQogICAgICAgIHZhciBwcm94eSA9IGZpbHRlcmVkUGFyYW1ldGVycy5pc0VtcHR5ID8gIlwocHJvdG90eXBlKSIgOiAiXChwcm90b3R5cGUpKFwocGFyYW1ldGVyc0Zvck1ldGhvZENhbGwoKSkpIgoKICAgICAgICBsZXQgY2FzdCA9ICJsZXQgcGVyZm9ybSA9IG1ldGhvZFBlcmZvcm1WYWx1ZSguXChwcm94eSkpIGFzPyBcKHR5cGUpIgogICAgICAgIGxldCBjYWxsID0gcGVyZm9ybVByb3h5Q2xvc3VyZUNhbGwoKQoKICAgICAgICByZXR1cm4gIlxuXHRcdFwoY2FzdClcblx0XHRcKGNhbGwpIgogICAgfQoKICAgIC8vIEhlbHBlcnMKICAgIHByaXZhdGUgZnVuYyBwYXJhbWV0ZXJzRm9yTWV0aG9kQ2FsbCgpIC0+IFN0cmluZyB7CiAgICAgICAgbGV0IGdlbmVyaWNzID0gZ2V0R2VuZXJpY3NXaXRob3V0Q29uc3RyYWludHMoKQogICAgICAgIHJldHVybiBwYXJhbWV0ZXJzLm1hcCB7ICQwLndyYXBwZWRGb3JDYWxscyhnZW5lcmljcywgaGFzQXZhaWxhYmlsaXR5KSB9LmpvaW5lZChzZXBhcmF0b3I6ICIsICIpCiAgICB9CgogICAgcHJpdmF0ZSBmdW5jIHBhcmFtZXRlcnNGb3JNZXRob2RUeXBlRGVjbGFyYXRpb24oYXZhaWxhYmlsaXR5OiBCb29sKSAtPiBTdHJpbmcgewogICAgICAgIGxldCBnZW5lcmljcyA9IGdldEdlbmVyaWNzV2l0aG91dENvbnN0cmFpbnRzKCkKICAgICAgICByZXR1cm4gcGFyYW1ldGVycy5tYXAgeyBwYXJhbSBpbgogICAgICAgICAgICBpZiBwYXJhbS5pc0dlbmVyaWMoZ2VuZXJpY3MpIHsgcmV0dXJuIHBhcmFtLmdlbmVyaWNUeXBlIH0KICAgICAgICAgICAgaWYgYXZhaWxhYmlsaXR5IHsgcmV0dXJuIHBhcmFtLnR5cGVFcmFzZWRUeXBlIH0KICAgICAgICAgICAgcmV0dXJuIHJlcGxhY2luZ1NlbGYocGFyYW0ubmVzdGVkVHlwZSkKICAgICAgICB9LmpvaW5lZChzZXBhcmF0b3I6ICIsICIpCiAgICB9CgogICAgcHJpdmF0ZSBmdW5jIHBhcmFtZXRlcnNGb3JQcm94eVNpZ25hdHVyZSgpIC0+IFN0cmluZyB7CiAgICAgICAgcmV0dXJuIHBhcmFtZXRlcnMubWFwIHsgcCBpbgogICAgICAgICAgICByZXR1cm4gIlwocC5sYWJlbEFuZE5hbWUoKSk6IFwocmVwbGFjaW5nU2VsZihwLm5lc3RlZFR5cGUpKSIKICAgICAgICB9LmpvaW5lZChzZXBhcmF0b3I6ICIsICIpCiAgICB9CgogICAgcHJpdmF0ZSBmdW5jIHBhcmFtZXRlcnNGb3JTdHViU2lnbmF0dXJlKCkgLT4gU3RyaW5nIHsKICAgICAgICBmdW5jIHJlcGxhY2luZyhmaXJzdDogU3RyaW5nLCBpbiBmdWxsOiBTdHJpbmcsIHdpdGggb3RoZXI6IFN0cmluZykgLT4gU3RyaW5nIHsKICAgICAgICAgICAgZ3VhcmQgbGV0IHJhbmdlID0gZnVsbC5yYW5nZShvZjogZmlyc3QpIGVsc2UgeyByZXR1cm4gZnVsbCB9CiAgICAgICAgICAgIHJldHVybiBmdWxsLnJlcGxhY2luZ0NoYXJhY3RlcnMoaW46IHJhbmdlLCB3aXRoOiBvdGhlcikKICAgICAgICB9CiAgICAgICAgbGV0IHByZWZpeCA9IG1ldGhvZC5zaG9ydE5hbWUKICAgICAgICBsZXQgZnVsbCA9IG1ldGhvZC5uYW1lCiAgICAgICAgbGV0IHJhbmdlID0gZnVsbC5yYW5nZShvZjogcHJlZml4KSEKICAgICAgICB2YXIgdW5yZWZpbmVkID0gIlwoZnVsbFtyYW5nZS51cHBlckJvdW5kLi4uXSkiCiAgICAgICAgcGFyYW1ldGVycy5tYXAgeyBwIC0+IChTdHJpbmcsU3RyaW5nKSBpbgogICAgICAgICAgICByZXR1cm4gKCJcKHAudHlwZSkiLCJcKHAuanVzdFR5cGUpIikKICAgICAgICB9LmZvckVhY2ggewogICAgICAgICAgICB1bnJlZmluZWQgPSByZXBsYWNpbmcoZmlyc3Q6ICQwLCBpbjogdW5yZWZpbmVkLCB3aXRoOiAkMSkKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHVucmVmaW5lZAogICAgfQoKICAgIHByaXZhdGUgZnVuYyBwYXJhbWV0ZXJzRm9yUHJveHlJbml0KCkgLT4gU3RyaW5nIHsKICAgICAgICBsZXQgZ2VuZXJpY3MgPSBnZXRHZW5lcmljc1dpdGhvdXRDb25zdHJhaW50cygpCiAgICAgICAgcmV0dXJuIHBhcmFtZXRlcnMubWFwIHsgIlwoJDAud3JhcHBlZEZvclByb3h5KGdlbmVyaWNzLCBoYXNBdmFpbGFiaWxpdHkpKSIgfS5qb2luZWQoc2VwYXJhdG9yOiAiLCAiKQogICAgfQoKICAgIHByaXZhdGUgZnVuYyBpc0dlbmVyaWMoKSAtPiBCb29sIHsKICAgICAgICByZXR1cm4gbWV0aG9kLnNob3J0TmFtZS5jb250YWlucygiPCIpICYmIG1ldGhvZC5zaG9ydE5hbWUuY29udGFpbnMoIj4iKQogICAgfQoKICAgIHByaXZhdGUgZnVuYyBnZXRWYXJpYWRpY1BhcmFtZXRlcnNOYW1lcygpIC0+IFtTdHJpbmddIHsKICAgICAgICBsZXQgcGF0dGVybiA9ICJbXFwofCxdKCAqW198XFx3XSogKT8gKihcXHcrKSAqXFw6ICooLis/XFwuXFwuXFwuKSIKICAgICAgICBsZXQgc3RyID0gbWV0aG9kLm5hbWUKICAgICAgICBsZXQgcmFuZ2UgPSBOU1JhbmdlKGxvY2F0aW9uOiAwLCBsZW5ndGg6IChzdHIgYXMgTlNTdHJpbmcpLmxlbmd0aCkKCiAgICAgICAgZ3VhcmQgbGV0IHJlZ2V4ID0gdHJ5PyBOU1JlZ3VsYXJFeHByZXNzaW9uKHBhdHRlcm46IHBhdHRlcm4pIGVsc2UgeyByZXR1cm4gW10gfQoKICAgICAgICB2YXIgcmVzdWx0OiBbU3RyaW5nXSA9IHJlZ2V4CiAgICAgICAgICAgIC5tYXRjaGVzKGluOiBzdHIsIG9wdGlvbnM6IFtdLCByYW5nZTogcmFuZ2UpCiAgICAgICAgICAgIC5jb21wYWN0TWFwIHsgbWF0Y2ggLT4gU3RyaW5nPyBpbgogICAgICAgICAgICAgICAgZ3VhcmQgbGV0IG5hbWVSYW5nZSA9IFJhbmdlKG1hdGNoLnJhbmdlKGF0OiAyKSwgaW46IHN0cikgZWxzZSB7IHJldHVybiBuaWwgfQogICAgICAgICAgICAgICAgcmV0dXJuIFN0cmluZyhzdHJbbmFtZVJhbmdlXSkKICAgICAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQKICAgIH0KCiAgICAvLy8gUmV0dXJucyBsaXN0IG9mIGdlbmVyaWNzIHVzZWQgaW4gbWV0aG9kIHNpZ25hdHVyZSwgd2l0aG91dCB0aGVpciBjb25zdHJhaW50cyAobGlrZSBbVCxVLFZdKQogICAgLy8vCiAgICAvLy8gLSBSZXR1cm5zOiBBcnJheSBvZiBzdHJpbmdzLCB3aGVyZSBlYWNoIHN0cmluZ3MgcmVwcmVzZW50IGdlbmVyaWMgbmFtZQogICAgcHJpdmF0ZSBmdW5jIGdldEdlbmVyaWNzV2l0aG91dENvbnN0cmFpbnRzKCkgLT4gW1N0cmluZ10gewogICAgICAgIGxldCBuYW1lID0gbWV0aG9kLnNob3J0TmFtZQogICAgICAgIGd1YXJkIGxldCBzdGFydCA9IG5hbWUuaW5kZXgob2Y6ICI8IiksIGxldCBlbmQgPSBuYW1lLmluZGV4KG9mOiAiPiIpIGVsc2UgeyByZXR1cm4gW10gfQoKICAgICAgICB2YXIgZ2VuUGFydCA9IG5hbWVbc3RhcnQuLi5lbmRdCiAgICAgICAgZ2VuUGFydC5yZW1vdmVGaXJzdCgpCiAgICAgICAgZ2VuUGFydC5yZW1vdmVMYXN0KCkKCiAgICAgICAgbGV0IHBhcnRzID0gZ2VuUGFydC5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogIiAiLCB3aXRoOiAiIikuY2hhcmFjdGVycy5zcGxpdChzZXBhcmF0b3I6ICIsIikubWFwKFN0cmluZy5pbml0KQogICAgICAgIHJldHVybiBwYXJ0cy5tYXAgeyBzdHJpcEdlblBhcnQocGFydDogJDApIH0KICAgIH0KCiAgICAvLy8gUmV0dXJucyBsaXN0IG9mIGdlbmVyaWMgY29uc3RyYWludGVzIGZyb20gbWV0aG9kIHNpZ25hdHVyZS4gRG9lcyBvbmx5IGNvbnRhaW4gc3R1ZmYgYmV0d2VlbiAnPCcgYW5kICc+JwogICAgLy8vCiAgICAvLy8gLSBSZXR1cm5zOiBBcnJheSBvZiBzdHJpbmdzLCBsaWtlIFsiVDogQ29kYWJsZSIsICJVOiBXaGF0ZXZlciJdCiAgICBwcml2YXRlIGZ1bmMgZ2V0R2VuZXJpY3NDb25zdHJhaW50cyhfIGdlbmVyaWNzOiBbU3RyaW5nXSwgZmlsdGVyU2luZ2xlOiBCb29sID0gdHJ1ZSkgLT4gW1N0cmluZ10gewogICAgICAgIGxldCBuYW1lID0gbWV0aG9kLnNob3J0TmFtZQogICAgICAgIGd1YXJkIGxldCBzdGFydCA9IG5hbWUuaW5kZXgob2Y6ICI8IiksIGxldCBlbmQgPSBuYW1lLmluZGV4KG9mOiAiPiIpIGVsc2UgeyByZXR1cm4gW10gfQoKICAgICAgICB2YXIgZ2VuUGFydCA9IG5hbWVbc3RhcnQuLi5lbmRdCiAgICAgICAgZ2VuUGFydC5yZW1vdmVGaXJzdCgpCiAgICAgICAgZ2VuUGFydC5yZW1vdmVMYXN0KCkKCiAgICAgICAgbGV0IHBhcnRzID0gZ2VuUGFydC5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogIiAiLCB3aXRoOiAiIikuY2hhcmFjdGVycy5zcGxpdChzZXBhcmF0b3I6ICIsIikubWFwKFN0cmluZy5pbml0KQogICAgICAgIHJldHVybiBwYXJ0cy5maWx0ZXIgewogICAgICAgICAgICBsZXQgY29tcG9uZW50cyA9ICQwLmNvbXBvbmVudHMoc2VwYXJhdGVkQnk6ICI6IikKICAgICAgICAgICAgcmV0dXJuIChjb21wb25lbnRzLmNvdW50ID09IDIgfHwgIWZpbHRlclNpbmdsZSkgJiYgZ2VuZXJpY3MuY29udGFpbnMoY29tcG9uZW50c1swXSkKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBmdW5jIGdldEdlbmVyaWNzQW1vbmdQYXJhbWV0ZXJzKCkgLT4gW1N0cmluZ10gewogICAgICAgIHJldHVybiBnZXRHZW5lcmljc1dpdGhvdXRDb25zdHJhaW50cygpLmZpbHRlciB7CiAgICAgICAgICAgIGZvciBwYXJhbSBpbiBzZWxmLnBhcmFtZXRlcnMgewogICAgICAgICAgICAgICAgaWYgcGFyYW0uaXNHZW5lcmljKFskMF0pIHsgcmV0dXJuIHRydWUgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBmYWxzZQogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGZ1bmMgd3JhcEdlbmVyaWNzKF8gZ2VuZXJpY3M6IFtTdHJpbmddKSAtPiBTdHJpbmcgewogICAgICAgIGd1YXJkICFnZW5lcmljcy5pc0VtcHR5IGVsc2UgeyByZXR1cm4gIiIgfQogICAgICAgIHJldHVybiAiPFwoZ2VuZXJpY3Muam9pbmVkKHNlcGFyYXRvcjoiLCIpKT4iCiAgICB9CgogICAgcHJpdmF0ZSBmdW5jIHN0cmlwR2VuUGFydChwYXJ0OiBTdHJpbmcpIC0+IFN0cmluZyB7CiAgICAgICAgcmV0dXJuIHBhcnQuY2hhcmFjdGVycy5zcGxpdChzZXBhcmF0b3I6ICI6IikubWFwKFN0cmluZy5pbml0KS5maXJzdCEKICAgIH0KCiAgICBwcml2YXRlIGZ1bmMgcmV0dXJuVHlwZVN0cmlwcGVkKF8gbWV0aG9kOiBTb3VyY2VyeVJ1bnRpbWUuTWV0aG9kLCB0eXBlOiBCb29sID0gZmFsc2UpIC0+IFN0cmluZyB7CiAgICAgICAgbGV0IHJldHVyblR5cGVSYXcgPSAiXChtZXRob2QucmV0dXJuVHlwZU5hbWUpIgogICAgICAgIHZhciBzdHJpcHBlZDogU3RyaW5nID0gewogICAgICAgICAgICBndWFyZCBsZXQgcmFuZ2UgPSByZXR1cm5UeXBlUmF3LnJhbmdlKG9mOiAid2hlcmUiKSBlbHNlIHsgcmV0dXJuIHJldHVyblR5cGVSYXcgfQogICAgICAgICAgICB2YXIgc3RyaXBwZWQgPSByZXR1cm5UeXBlUmF3CiAgICAgICAgICAgIHN0cmlwcGVkLnJlbW92ZVN1YnJhbmdlKChyYW5nZS5sb3dlckJvdW5kKS4uLikKICAgICAgICAgICAgcmV0dXJuIHN0cmlwcGVkCiAgICAgICAgfSgpCiAgICAgICAgc3RyaXBwZWQgPSBzdHJpcHBlZC50cmltbWluZ0NoYXJhY3RlcnMoaW46IENoYXJhY3RlclNldChjaGFyYWN0ZXJzSW46ICIgIikpCiAgICAgICAgZ3VhcmQgdHlwZSBlbHNlIHsgcmV0dXJuIHN0cmlwcGVkIH0KICAgICAgICByZXR1cm4gIihcKHN0cmlwcGVkKSkuVHlwZSIKICAgIH0KCiAgICBwcml2YXRlIGZ1bmMgd2hlcmVDbGF1c2VDb25zdHJhaW50cygpIC0+IFtTdHJpbmddIHsKICAgICAgICBsZXQgcmV0dXJuVHlwZVJhdyA9IG1ldGhvZC5yZXR1cm5UeXBlTmFtZS5uYW1lCiAgICAgICAgZ3VhcmQgbGV0IHJhbmdlID0gcmV0dXJuVHlwZVJhdy5yYW5nZShvZjogIndoZXJlIikgZWxzZSB7IHJldHVybiBbXSB9CiAgICAgICAgdmFyIHdoZXJlQ2xhdXNlID0gcmV0dXJuVHlwZVJhdwogICAgICAgIHdoZXJlQ2xhdXNlLnJlbW92ZVN1YnJhbmdlKC4uLihyYW5nZS51cHBlckJvdW5kKSkKICAgICAgICByZXR1cm4gd2hlcmVDbGF1c2UKICAgICAgICAgICAgLnRyaW1taW5nQ2hhcmFjdGVycyhpbjogQ2hhcmFjdGVyU2V0LndoaXRlc3BhY2VzQW5kTmV3bGluZXMpCiAgICAgICAgICAgIC5jb21wb25lbnRzKHNlcGFyYXRlZEJ5OiAiLCIpCiAgICB9CgogICAgcHJpdmF0ZSBmdW5jIHdoZXJlQ2xhdXNlRXhwcmVzc2lvbigpIC0+IFN0cmluZyB7CiAgICAgICAgbGV0IGNvbnN0cmFpbnRzID0gd2hlcmVDbGF1c2VDb25zdHJhaW50cygpCiAgICAgICAgaWYgY29uc3RyYWludHMuaXNFbXB0eSB7CiAgICAgICAgICAgIHJldHVybiAiIgogICAgICAgIH0KICAgICAgICByZXR1cm4gIiB3aGVyZSAiICsgY29uc3RyYWludHMuam9pbmVkKHNlcGFyYXRvcjogIiwgIikKICAgIH0KCiAgICBwcml2YXRlIGZ1bmMgbWV0aG9kSW5mbygpIC0+IChhbm5vdGF0aW9uOiBTdHJpbmcsIG1ldGhvZE5hbWU6IFN0cmluZywgZ2VuZXJpY0NvbnN0cmFpbnM6IFN0cmluZykgewogICAgICAgIGxldCBnZW5lcmljcyA9IGdldEdlbmVyaWNzQW1vbmdQYXJhbWV0ZXJzKCkKICAgICAgICBsZXQgbWV0aG9kTmFtZSA9IHJldHVyblR5cGVNYXR0ZXJzKCkgPyBtZXRob2Quc2hvcnROYW1lIDogIlwobWV0aG9kLmNhbGxOYW1lKVwod3JhcEdlbmVyaWNzKGdlbmVyaWNzKSkiCiAgICAgICAgbGV0IGNvbnN0cmFpbnRzOiBTdHJpbmcgPSB7CiAgICAgICAgICAgIGxldCBjb25zdHJhaW50czogW1N0cmluZ10KICAgICAgICAgICAgaWYgcmV0dXJuVHlwZU1hdHRlcnMoKSB7CiAgICAgICAgICAgICAgICBjb25zdHJhaW50cyA9IHdoZXJlQ2xhdXNlQ29uc3RyYWludHMoKQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgY29uc3RyYWludHMgPSBnZXRHZW5lcmljc0NvbnN0cmFpbnRzKGdlbmVyaWNzKQogICAgICAgICAgICB9CiAgICAgICAgICAgIGd1YXJkICFjb25zdHJhaW50cy5pc0VtcHR5IGVsc2UgeyByZXR1cm4gIiIgfQoKICAgICAgICAgICAgcmV0dXJuICIgd2hlcmUgXChjb25zdHJhaW50cy5qb2luZWQoc2VwYXJhdG9yOiAiLCAiKSkiCiAgICAgICAgfSgpCiAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSBzZWxmLm1ldGhvZEF0dHJpYnV0ZXNOb25PYmpjCiAgICAgICAgYXR0cmlidXRlcyA9IGF0dHJpYnV0ZXMuY29uZGVuc2VXaGl0ZXNwYWNlKCkKICAgICAgICBhdHRyaWJ1dGVzID0gYXR0cmlidXRlcy5pc0VtcHR5ID8gIiIgOiAiXChhdHRyaWJ1dGVzKVxuXHRcdCIKICAgICAgICByZXR1cm4gKGF0dHJpYnV0ZXMsIG1ldGhvZE5hbWUsIGNvbnN0cmFpbnRzKQogICAgfQp9CgpleHRlbnNpb24gU3RyaW5nIHsKICAgIGZ1bmMgY29uZGVuc2VXaGl0ZXNwYWNlKCkgLT4gU3RyaW5nIHsKICAgICAgICBsZXQgY29tcG9uZW50cyA9IHNlbGYuY29tcG9uZW50cyhzZXBhcmF0ZWRCeTogLndoaXRlc3BhY2VzQW5kTmV3bGluZXMpCiAgICAgICAgcmV0dXJuIGNvbXBvbmVudHMuZmlsdGVyIHsgISQwLmlzRW1wdHkgfS5qb2luZWQoc2VwYXJhdG9yOiAiICIpCiAgICB9Cn0KY2xhc3MgU3Vic2NyaXB0V3JhcHBlciB7CiAgICBsZXQgd3JhcHBlZDogU291cmNlcnlSdW50aW1lLlN1YnNjcmlwdAogICAgdmFyIHJlYWRvbmx5OiBCb29sIHsgcmV0dXJuICF3cmFwcGVkLmlzTXV0YWJsZSB9CiAgICB2YXIgd3JhcHBlZFBhcmFtZXRlcnM6IFtQYXJhbWV0ZXJXcmFwcGVyXSB7IHJldHVybiB3cmFwcGVkLnBhcmFtZXRlcnMubWFwIHsgUGFyYW1ldGVyV3JhcHBlcigkMCkgfSB9CiAgICB2YXIgY2FzZXNDb3VudDogSW50IHsgcmV0dXJuIHJlYWRvbmx5ID8gMSA6IDIgfQogICAgdmFyIG5lc3RlZFR5cGU6IFN0cmluZyB7IHJldHVybiAiXChUeXBlV3JhcHBlcih3cmFwcGVkLnJldHVyblR5cGVOYW1lKS5uZXN0ZWRQYXJhbWV0ZXIpIiB9CiAgICBsZXQgYXNzb2NpYXRlZFR5cGVzOiBbU3RyaW5nXT8KICAgIGxldCBnZW5lcmljVHlwZXNMaXN0OiBbU3RyaW5nXQogICAgbGV0IGdlbmVyaWNUeXBlc01vZGlmaWVyOiBTdHJpbmc/CiAgICBsZXQgd2hlcmVDbGF1c2U6IFN0cmluZwogICAgdmFyIGhhc0F2YWlsYWJpbGl0eTogQm9vbCB7IHdyYXBwZWQuYXR0cmlidXRlc1siYXZhaWxhYmxlIl0/LmlzRW1wdHkgPT0gZmFsc2UgfQoKICAgIHByaXZhdGUgdmFyIG1ldGhvZEF0dHJpYnV0ZXM6IFN0cmluZyB7CiAgICAgICAgcmV0dXJuIEhlbHBlcnMuZXh0cmFjdEF0dHJpYnV0ZXMoZnJvbTogc2VsZi53cmFwcGVkLmF0dHJpYnV0ZXMsIGZpbHRlck91dFN0YXJ0aW5nV2l0aDogWyJtdXRhdGluZyIsICJAaW5saW5hYmxlIl0pCiAgICB9CiAgICBwcml2YXRlIHZhciBtZXRob2RBdHRyaWJ1dGVzTm9uT2JqYzogU3RyaW5nIHsKICAgICAgICByZXR1cm4gSGVscGVycy5leHRyYWN0QXR0cmlidXRlcyhmcm9tOiBzZWxmLndyYXBwZWQuYXR0cmlidXRlcywgZmlsdGVyT3V0U3RhcnRpbmdXaXRoOiBbIm11dGF0aW5nIiwgIkBpbmxpbmFibGUiLCAiQG9iamMiXSkKICAgIH0KCiAgICBwcml2YXRlIGxldCBub1N0dWJEZWZpbmVkTWVzc2FnZSA9ICJTdHViIHJldHVybiB2YWx1ZSBub3Qgc3BlY2lmaWVkIGZvciBzdWJzY3JpcHQuIFVzZSBnaXZlbiBmaXJzdC4iCgogICAgcHJpdmF0ZSBzdGF0aWMgdmFyIHJlZ2lzdGVyZWQ6IFtTdHJpbmc6IEludF0gPSBbOl0KICAgIHByaXZhdGUgc3RhdGljIHZhciBuYW1lc1dpdGhvdXRSZXR1cm5UeXBlOiBbU3RyaW5nOiBJbnRdID0gWzpdCiAgICBwcml2YXRlIHN0YXRpYyB2YXIgc3VmZml4ZXM6IFtTdHJpbmc6IEludF0gPSBbOl0KICAgIHB1YmxpYyBzdGF0aWMgZnVuYyBjbGVhcigpIC0+IFN0cmluZyB7CiAgICAgICAgU3Vic2NyaXB0V3JhcHBlci5yZWdpc3RlcmVkID0gWzpdCiAgICAgICAgU3Vic2NyaXB0V3JhcHBlci5zdWZmaXhlcyA9IFs6XQogICAgICAgIG5hbWVzV2l0aG91dFJldHVyblR5cGUgPSBbOl0KICAgICAgICByZXR1cm4gIiIKICAgIH0KICAgIHN0YXRpYyBmdW5jIHJlZ2lzdGVyKF8gbmFtZTogU3RyaW5nLCBfIHVuaXF1ZU5hbWU6IFN0cmluZykgewogICAgICAgIGxldCBjb3VudCA9IFN1YnNjcmlwdFdyYXBwZXIucmVnaXN0ZXJlZFtuYW1lXSA/PyAwCiAgICAgICAgU3Vic2NyaXB0V3JhcHBlci5yZWdpc3RlcmVkW25hbWVdID0gY291bnQgKyAxCiAgICAgICAgU3Vic2NyaXB0V3JhcHBlci5zdWZmaXhlc1t1bmlxdWVOYW1lXSA9IGNvdW50ICsgMQogICAgfQogICAgc3RhdGljIGZ1bmMgcmVnaXN0ZXIoc2hvcnQgbmFtZTogU3RyaW5nKSB7CiAgICAgICAgbGV0IGNvdW50ID0gU3Vic2NyaXB0V3JhcHBlci5uYW1lc1dpdGhvdXRSZXR1cm5UeXBlW25hbWVdID8/IDAKICAgICAgICBTdWJzY3JpcHRXcmFwcGVyLm5hbWVzV2l0aG91dFJldHVyblR5cGVbbmFtZV0gPSBjb3VudCArIDEKICAgIH0KCiAgICBmdW5jIHJlZ2lzdGVyKCkgewogICAgICAgIFN1YnNjcmlwdFdyYXBwZXIucmVnaXN0ZXIocmVnaXN0cmF0aW9uTmFtZSgiZ2V0IiksdW5pcXVlTmFtZSkKICAgICAgICBTdWJzY3JpcHRXcmFwcGVyLnJlZ2lzdGVyKHNob3J0OiBzaG9ydE5hbWUpCiAgICAgICAgZ3VhcmQgIXJlYWRvbmx5IGVsc2UgeyByZXR1cm4gfQogICAgICAgIFN1YnNjcmlwdFdyYXBwZXIucmVnaXN0ZXIocmVnaXN0cmF0aW9uTmFtZSgic2V0IiksdW5pcXVlTmFtZSkKICAgIH0KCiAgICBpbml0KF8gd3JhcHBlZDogU291cmNlcnlSdW50aW1lLlN1YnNjcmlwdCkgewogICAgICAgIHNlbGYud3JhcHBlZCA9IHdyYXBwZWQKICAgICAgICBhc3NvY2lhdGVkVHlwZXMgPSBIZWxwZXJzLmV4dHJhY3RBc3NvY2lhdGVkVHlwZXMoZnJvbTogd3JhcHBlZCkKICAgICAgICBnZW5lcmljVHlwZXNMaXN0ID0gSGVscGVycy5leHRyYWN0R2VuZXJpY3NMaXN0KGFzc29jaWF0ZWRUeXBlcykKICAgICAgICB3aGVyZUNsYXVzZSA9IEhlbHBlcnMuZXh0cmFjdFdoZXJlQ2xhdXNlKGZyb206IHdyYXBwZWQpID8/ICIiCiAgICAgICAgaWYgbGV0IHR5cGVzID0gYXNzb2NpYXRlZFR5cGVzIHsKICAgICAgICAgICAgZ2VuZXJpY1R5cGVzTW9kaWZpZXIgPSAiPFwodHlwZXMuam9pbmVkKHNlcGFyYXRvcjogIiwiKSk+IgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGdlbmVyaWNUeXBlc01vZGlmaWVyID0gbmlsCiAgICAgICAgfQogICAgfQoKICAgIGZ1bmMgcmVnaXN0cmF0aW9uTmFtZShfIGFjY2Vzc29yOiBTdHJpbmcpIC0+IFN0cmluZyB7CiAgICAgICAgcmV0dXJuICJzdWJzY3JpcHRfXChhY2Nlc3NvcilfXCh3cmFwcGVkUGFyYW1ldGVycy5tYXAoeyAkMC5zYW5pdGl6ZWRGb3JFbnVtQ2FzZU5hbWUoKSB9KS5qb2luZWQoc2VwYXJhdG9yOiAiXyIpKSIKICAgIH0KICAgIHZhciBzaG9ydE5hbWU6IFN0cmluZyB7IHJldHVybiAicHVibGljIHN1YnNjcmlwdFwoZ2VuZXJpY1R5cGVzTW9kaWZpZXIgPz8gIiAiKShcKHdyYXBwZWRQYXJhbWV0ZXJzLm1hcCh7ICQwLmFzTWV0aG9kQXJndW1lbnQoKSB9KS5qb2luZWQoc2VwYXJhdG9yOiAiLCAiKSkpIiB9CiAgICB2YXIgdW5pcXVlTmFtZTogU3RyaW5nIHsgcmV0dXJuICJcKHNob3J0TmFtZSkgLT4gXCh3cmFwcGVkLnJldHVyblR5cGVOYW1lKVwoc2VsZi53aGVyZUNsYXVzZSkiIH0KCiAgICBwcml2YXRlIGZ1bmMgbmFtZVN1ZmZpeChfIGFjY2Vzc29yOiBTdHJpbmcpIC0+IFN0cmluZyB7CiAgICAgICAgZ3VhcmQgbGV0IGNvdW50ID0gU3Vic2NyaXB0V3JhcHBlci5yZWdpc3RlcmVkW3JlZ2lzdHJhdGlvbk5hbWUoYWNjZXNzb3IpXSBlbHNlIHsgcmV0dXJuICIiIH0KICAgICAgICBndWFyZCBjb3VudCA+IDEgZWxzZSB7IHJldHVybiAiIiB9CiAgICAgICAgZ3VhcmQgbGV0IGluZGV4ID0gU3Vic2NyaXB0V3JhcHBlci5zdWZmaXhlc1t1bmlxdWVOYW1lXSBlbHNlIHsgcmV0dXJuICIiIH0KICAgICAgICByZXR1cm4gIl9cKGluZGV4KSIKICAgIH0KCiAgICAvLyBjYWxsCiAgICBmdW5jIHN1YnNjcmlwdENhbGwoKSAtPiBTdHJpbmcgewogICAgICAgIGxldCBnZXQgPSAiXG5cdFx0Z2V0IHtcKGdldHRlcigpKVxuXHRcdH0iCiAgICAgICAgbGV0IHNldCA9IHJlYWRvbmx5ID8gIiIgOiAiXG5cdFx0c2V0IHtcKHNldHRlcigpKVxuXHRcdH0iCiAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSBzZWxmLm1ldGhvZEF0dHJpYnV0ZXNOb25PYmpjCiAgICAgICAgYXR0cmlidXRlcyA9IGF0dHJpYnV0ZXMuaXNFbXB0eSA/ICIiIDogIlwoYXR0cmlidXRlcylcblx0IgogICAgICAgIHJldHVybiAiXChhdHRyaWJ1dGVzKVwodW5pcXVlTmFtZSkge1woZ2V0KVwoc2V0KVxuXHR9IgogICAgfQogICAgcHJpdmF0ZSBmdW5jIGdldHRlcigpIC0+IFN0cmluZyB7CiAgICAgICAgbGV0IG1ldGhvZCA9ICIuXChzdWJzY3JpcHRDYXNlUHJlZml4KCJnZXQiKSkoXChwYXJhbWV0ZXJzRm9yTWV0aG9kQ2FsbCgpKSkiCiAgICAgICAgbGV0IG9wdGlvbmFsUmV0dXJuV29ya2Fyb3VuZCA9ICJcKHdyYXBwZWQucmV0dXJuVHlwZU5hbWUpIi5oYXNTdWZmaXgoIj8iKQogICAgICAgIGxldCBub1N0dWJEZWZpbmVkID0gKG9wdGlvbmFsUmV0dXJuV29ya2Fyb3VuZCB8fCB3cmFwcGVkLnJldHVyblR5cGVOYW1lLmlzT3B0aW9uYWwpID8gInJldHVybiBuaWwiIDogIm9uRmF0YWxGYWlsdXJlKFwiXChub1N0dWJEZWZpbmVkTWVzc2FnZSlcIik7IEZhaWx1cmUoXCJub1N0dWJEZWZpbmVkTWVzc2FnZVwiKSIKICAgICAgICByZXR1cm4KICAgICAgICAgICAgIlxuXHRcdFx0YWRkSW52b2NhdGlvbihcKG1ldGhvZCkpIiArCiAgICAgICAgICAgICAgICAiXG5cdFx0XHRkbyB7IiArCiAgICAgICAgICAgICAgICAiXG5cdFx0XHRcdHJldHVybiB0cnkgbWV0aG9kUmV0dXJuVmFsdWUoXChtZXRob2QpKS5jYXN0ZWQoKSIgKwogICAgICAgICAgICAgICAgIlxuXHRcdFx0fSBjYXRjaCB7IiArCiAgICAgICAgICAgICAgICAiXG5cdFx0XHRcdFwobm9TdHViRGVmaW5lZCkiICsKICAgICAgICAiXG5cdFx0XHR9IgogICAgfQogICAgcHJpdmF0ZSBmdW5jIHNldHRlcigpIC0+IFN0cmluZyB7CiAgICAgICAgbGV0IG1ldGhvZCA9ICIuXChzdWJzY3JpcHRDYXNlUHJlZml4KCJzZXQiKSkoXChwYXJhbWV0ZXJzRm9yTWV0aG9kQ2FsbChzZXQ6IHRydWUpKSkiCiAgICAgICAgcmV0dXJuICJcblx0XHRcdGFkZEludm9jYXRpb24oXChtZXRob2QpKSIKICAgIH0KCiAgICB2YXIgYXNzZXJ0aW9uTmFtZTogU3RyaW5nIHsKICAgICAgICByZXR1cm4gcmVhZG9ubHkgPyBhc3NlcnRpb25OYW1lKCJnZXQiKSA6ICJcKGFzc2VydGlvbk5hbWUoImdldCIpKVxuXHRcdFx0XChhc3NlcnRpb25OYW1lKCJzZXQiKSkiCiAgICB9CiAgICBwcml2YXRlIGZ1bmMgYXNzZXJ0aW9uTmFtZShfIGFjY2Vzc29yOiBTdHJpbmcpIC0+IFN0cmluZyB7CiAgICAgICAgcmV0dXJuICJjYXNlIC5cKHN1YnNjcmlwdENhc2VQcmVmaXgoYWNjZXNzb3IpKTogcmV0dXJuICIgKwogICAgICAgICAgICAiXCJbXChhY2Nlc3NvcildIGBzdWJzY3JpcHRgXChnZW5lcmljVHlwZXNNb2RpZmllciA/PyAiIilbXChwYXJhbWV0ZXJzRm9yQXNzZXJ0aW9uTmFtZSgpKV1cIiIKICAgIH0KCiAgICAvLyBtZXRob2QgdHlwZQogICAgZnVuYyBzdWJzY3JpcHRDYXNlUHJlZml4KF8gYWNjZXNzb3I6IFN0cmluZykgLT4gU3RyaW5nIHsKICAgICAgICByZXR1cm4gIlwocmVnaXN0cmF0aW9uTmFtZShhY2Nlc3NvcikpXChuYW1lU3VmZml4KGFjY2Vzc29yKSkiCiAgICB9CiAgICBmdW5jIHN1YnNjcmlwdENhc2VOYW1lKF8gYWNjZXNzb3I6IFN0cmluZywgYXZhaWxhYmlsaXR5OiBCb29sID0gZmFsc2UpIC0+IFN0cmluZyB7CiAgICAgICAgcmV0dXJuICJcKHN1YnNjcmlwdENhc2VQcmVmaXgoYWNjZXNzb3IpKShcKHBhcmFtZXRlcnNGb3JNZXRob2RUeXBlRGVjbGFyYXRpb24oYXZhaWxhYmlsaXR5OiBhdmFpbGFiaWxpdHksIHNldDogYWNjZXNzb3IgPT0gInNldCIpKSkiCiAgICB9CiAgICBmdW5jIHN1YnNjcmlwdENhc2VzKCkgLT4gU3RyaW5nIHsKICAgICAgICBpZiByZWFkb25seSB7CiAgICAgICAgICAgIHJldHVybiAiY2FzZSBcKHN1YnNjcmlwdENhc2VOYW1lKCJnZXQiLCBhdmFpbGFiaWxpdHk6IGhhc0F2YWlsYWJpbGl0eSkpIgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAiY2FzZSBcKHN1YnNjcmlwdENhc2VOYW1lKCJnZXQiLCBhdmFpbGFiaWxpdHk6IGhhc0F2YWlsYWJpbGl0eSkpXG5cdFx0Y2FzZSBcKHN1YnNjcmlwdENhc2VOYW1lKCJzZXQiLCBhdmFpbGFiaWxpdHk6IGhhc0F2YWlsYWJpbGl0eSkpIgogICAgICAgIH0KICAgIH0KICAgIGZ1bmMgZXF1YWxDYXNlKF8gYWNjZXNzb3I6IFN0cmluZykgLT4gU3RyaW5nIHsKICAgICAgICB2YXIgbGhzUGFyYW1zID0gd3JhcHBlZC5wYXJhbWV0ZXJzLm1hcCB7ICJsaHNcKCQwLm5hbWUuY2FwaXRhbGl6ZWQpIiB9LmpvaW5lZChzZXBhcmF0b3I6ICIsICIpCiAgICAgICAgdmFyIHJoc1BhcmFtcyA9IHdyYXBwZWQucGFyYW1ldGVycy5tYXAgeyAicmhzXCgkMC5uYW1lLmNhcGl0YWxpemVkKSIgfS5qb2luZWQoc2VwYXJhdG9yOiAiLCAiKQogICAgICAgIHZhciBjb21wYXJhdG9ycyA9ICJcdFx0XHRcdHZhciByZXN1bHRzOiBbTWF0Y2hlci5QYXJhbWV0ZXJDb21wYXJpc29uUmVzdWx0XSA9IFtdXG4iCiAgICAgICAgY29tcGFyYXRvcnMgKz0gd3JhcHBlZFBhcmFtZXRlcnMubWFwIHsgIlx0XHRcdFx0XCgkMC5jb21wYXJhdG9yUmVzdWx0KCkpIiB9LmpvaW5lZChzZXBhcmF0b3I6ICJcbiIpCgogICAgICAgIGlmIGFjY2Vzc29yID09ICJzZXQiIHsKICAgICAgICAgICAgbGhzUGFyYW1zICs9ICIsIGxoc0RpZFNldCIKICAgICAgICAgICAgcmhzUGFyYW1zICs9ICIsIHJoc0RpZFNldCIKICAgICAgICAgICAgY29tcGFyYXRvcnMgKz0gIlxuXHRcdFx0XHRyZXN1bHRzLmFwcGVuZChNYXRjaGVyLlBhcmFtZXRlckNvbXBhcmlzb25SZXN1bHQoUGFyYW1ldGVyLmNvbXBhcmUobGhzOiBsaHNEaWRTZXQsIHJoczogcmhzRGlkU2V0LCB3aXRoOiBtYXRjaGVyKSwgbGhzRGlkU2V0LCByaHNEaWRTZXQsIFwibmV3VmFsdWVcIikpIgogICAgICAgIH0KCiAgICAgICAgY29tcGFyYXRvcnMgKz0gIlxuXHRcdFx0XHRyZXR1cm4gTWF0Y2hlci5Db21wYXJpc29uUmVzdWx0KHJlc3VsdHMpIgoKICAgICAgICAvLyBjb21wYXJhdG9yUmVzdWx0KCkKICAgICAgICByZXR1cm4gImNhc2UgKGxldCAuXChzdWJzY3JpcHRDYXNlUHJlZml4KGFjY2Vzc29yKSkoXChsaHNQYXJhbXMpKSwgbGV0IC5cKHN1YnNjcmlwdENhc2VQcmVmaXgoYWNjZXNzb3IpKShcKHJoc1BhcmFtcykpKTpcbiIgKyBjb21wYXJhdG9ycwogICAgfQogICAgZnVuYyBlcXVhbENhc2VzKCkgLT4gU3RyaW5nIHsKICAgICAgICByZXR1cm4gcmVhZG9ubHkgPyBlcXVhbENhc2UoImdldCIpIDogIlwoZXF1YWxDYXNlKCJnZXQiKSlcblx0XHRcdFwoZXF1YWxDYXNlKCJzZXQiKSkiCiAgICB9CiAgICBmdW5jIGludFZhbHVlQ2FzZSgpIC0+IFN0cmluZyB7CiAgICAgICAgcmV0dXJuIHJlYWRvbmx5ID8gaW50VmFsdWVDYXNlKCJnZXQiKSA6ICJcKGludFZhbHVlQ2FzZSgiZ2V0IikpXG5cdFx0XHRcKGludFZhbHVlQ2FzZSgic2V0IikpIgogICAgfQogICAgZnVuYyBpbnRWYWx1ZUNhc2UoXyBhY2Nlc3NvcjogU3RyaW5nKSAtPiBTdHJpbmcgewogICAgICAgIGxldCBwYXJhbXMgPSB3cmFwcGVkUGFyYW1ldGVycy5lbnVtZXJhdGVkKCkubWFwIHsgb2Zmc2V0LCBfIGluCiAgICAgICAgICAgIHJldHVybiAicFwob2Zmc2V0KSIKICAgICAgICB9CiAgICAgICAgbGV0IGRlZmluaXRpb25zID0gcGFyYW1zLmpvaW5lZChzZXBhcmF0b3I6ICIsICIpICsgKGFjY2Vzc29yID09ICJzZXQiID8gIiwgXyIgOiAiIikKICAgICAgICBsZXQgcGFyYW1zU3VtID0gcGFyYW1zLm1hcCh7ICJcKCQwKS5pbnRWYWx1ZSIgfSkuam9pbmVkKHNlcGFyYXRvcjogIiArICIpCiAgICAgICAgcmV0dXJuICJjYXNlIGxldCAuXChzdWJzY3JpcHRDYXNlUHJlZml4KGFjY2Vzc29yKSkoXChkZWZpbml0aW9ucykpOiByZXR1cm4gXChwYXJhbXNTdW0pIgogICAgfQoKICAgIC8vIEdpdmVuCiAgICBmdW5jIGdpdmVuQ29uc3RydWN0b3JOYW1lKCkgLT4gU3RyaW5nIHsKICAgICAgICBsZXQgcmV0dXJuVHlwZVN0cmluZyA9IHJldHVybnNTZWxmID8gcmVwbGFjZVNlbGYgOiBUeXBlV3JhcHBlcih3cmFwcGVkLnJldHVyblR5cGVOYW1lKS5zdHJpcHBlZAogICAgICAgIHZhciBhdHRyaWJ1dGVzID0gc2VsZi5tZXRob2RBdHRyaWJ1dGVzTm9uT2JqYwogICAgICAgIGF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzLmlzRW1wdHkgPyAiIiA6ICJcKGF0dHJpYnV0ZXMpXG5cdFx0IgogICAgICAgIHJldHVybiAiXChhdHRyaWJ1dGVzKXB1YmxpYyBzdGF0aWMgZnVuYyBgc3Vic2NyaXB0YFwoZ2VuZXJpY1R5cGVzTW9kaWZpZXIgPz8gIiIpKFwocGFyYW1ldGVyc0ZvclByb3h5U2lnbmF0dXJlKCkpLCB3aWxsUmV0dXJuOiBcKHJldHVyblR5cGVTdHJpbmcpLi4uKSAtPiBTdWJzY3JpcHRTdHViIgogICAgfQogICAgZnVuYyBnaXZlbkNvbnN0cnVjdG9yKCkgLT4gU3RyaW5nIHsKICAgICAgICByZXR1cm4gInJldHVybiBHaXZlbihtZXRob2Q6IC5cKHN1YnNjcmlwdENhc2VQcmVmaXgoImdldCIpKShcKHBhcmFtZXRlcnNGb3JQcm94eUluaXQoKSkpLCBwcm9kdWN0czogd2lsbFJldHVybi5tYXAoeyBTdHViUHJvZHVjdC5yZXR1cm4oJDAgYXMgQW55KSB9KSkiCiAgICB9CgogICAgLy8gVmVyaWZ5CiAgICBmdW5jIHZlcmlmeUNvbnN0cnVjdG9yTmFtZShzZXQ6IEJvb2wgPSBmYWxzZSkgLT4gU3RyaW5nIHsKICAgICAgICBsZXQgcmV0dXJuVHlwZVN0cmluZyA9IHJldHVybnNTZWxmID8gcmVwbGFjZVNlbGYgOiBuZXN0ZWRUeXBlCiAgICAgICAgbGV0IHJldHVybmluZyA9IHNldCA/ICIiIDogcmV0dXJuaW5nUGFyYW1ldGVyKHRydWUsIHRydWUpCiAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSBzZWxmLm1ldGhvZEF0dHJpYnV0ZXNOb25PYmpjCiAgICAgICAgYXR0cmlidXRlcyA9IGF0dHJpYnV0ZXMuaXNFbXB0eSA/ICIiIDogIlwoYXR0cmlidXRlcylcblx0XHQiCiAgICAgICAgcmV0dXJuICJcKGF0dHJpYnV0ZXMpcHVibGljIHN0YXRpYyBmdW5jIGBzdWJzY3JpcHRgXChnZW5lcmljVHlwZXNNb2RpZmllciA/PyAiIikoXChwYXJhbWV0ZXJzRm9yUHJveHlTaWduYXR1cmUoKSlcKHJldHVybmluZylcKHNldCA/ICIsIHNldCBuZXdWYWx1ZTogXChyZXR1cm5UeXBlU3RyaW5nKSIgOiAiIikpIC0+IFZlcmlmeSIKICAgIH0KICAgIGZ1bmMgdmVyaWZ5Q29uc3RydWN0b3Ioc2V0OiBCb29sID0gZmFsc2UpIC0+IFN0cmluZyB7CiAgICAgICAgcmV0dXJuICJyZXR1cm4gVmVyaWZ5KG1ldGhvZDogLlwoc3Vic2NyaXB0Q2FzZVByZWZpeChzZXQgPyAic2V0IiA6ICJnZXQiKSkoXChwYXJhbWV0ZXJzRm9yUHJveHlJbml0KHNldDogc2V0KSkpKSIKICAgIH0KCiAgICAvLyBHZW5lcmljcwogICAgcHJpdmF0ZSBmdW5jIGdldEdlbmVyaWNzKCkgLT4gW1N0cmluZ10gewogICAgICAgIHJldHVybiBnZW5lcmljVHlwZXNMaXN0CiAgICB9CgogICAgLy8gSGVscGVycwogICAgcHJpdmF0ZSB2YXIgcmV0dXJuc1NlbGY6IEJvb2wgeyByZXR1cm4gVHlwZVdyYXBwZXIod3JhcHBlZC5yZXR1cm5UeXBlTmFtZSkuaXNTZWxmVHlwZSB9CiAgICBwcml2YXRlIHZhciByZXBsYWNlU2VsZjogU3RyaW5nIHsgcmV0dXJuIEN1cnJlbnQuc2VsZlR5cGUgfQogICAgcHJpdmF0ZSBmdW5jIHJldHVyblR5cGVTdHJpcHBlZCh0eXBlOiBCb29sID0gZmFsc2UpIC0+IFN0cmluZyB7CiAgICAgICAgbGV0IHJldHVyblR5cGVSYXcgPSAiXCh3cmFwcGVkLnJldHVyblR5cGVOYW1lKSIKICAgICAgICB2YXIgc3RyaXBwZWQ6IFN0cmluZyA9IHsKICAgICAgICAgICAgZ3VhcmQgbGV0IHJhbmdlID0gcmV0dXJuVHlwZVJhdy5yYW5nZShvZjogIndoZXJlIikgZWxzZSB7IHJldHVybiByZXR1cm5UeXBlUmF3IH0KICAgICAgICAgICAgdmFyIHN0cmlwcGVkID0gcmV0dXJuVHlwZVJhdwogICAgICAgICAgICBzdHJpcHBlZC5yZW1vdmVTdWJyYW5nZSgocmFuZ2UubG93ZXJCb3VuZCkuLi4pCiAgICAgICAgICAgIHJldHVybiBzdHJpcHBlZAogICAgICAgIH0oKQogICAgICAgIHN0cmlwcGVkID0gc3RyaXBwZWQudHJpbW1pbmdDaGFyYWN0ZXJzKGluOiBDaGFyYWN0ZXJTZXQoY2hhcmFjdGVyc0luOiAiICIpKQogICAgICAgIGd1YXJkIHR5cGUgZWxzZSB7IHJldHVybiBzdHJpcHBlZCB9CiAgICAgICAgcmV0dXJuICIoXChzdHJpcHBlZCkpLlR5cGUiCiAgICB9CiAgICBwcml2YXRlIGZ1bmMgcmV0dXJuVHlwZU1hdHRlcnMoKSAtPiBCb29sIHsKICAgICAgICBsZXQgY291bnQgPSBTdWJzY3JpcHRXcmFwcGVyLm5hbWVzV2l0aG91dFJldHVyblR5cGVbc2hvcnROYW1lXSA/PyAwCiAgICAgICAgcmV0dXJuIGNvdW50ID4gMQogICAgfQoKICAgIC8vIHBhcmFtcwogICAgcHJpdmF0ZSBmdW5jIHJldHVybmluZ1BhcmFtZXRlcihfIG11bHRpcGxlOiBCb29sLCBfIGZyb250OiBCb29sKSAtPiBTdHJpbmcgewogICAgICAgIGd1YXJkIHJldHVyblR5cGVNYXR0ZXJzKCkgZWxzZSB7IHJldHVybiAiIiB9CiAgICAgICAgbGV0IHJldHVybmluZzogU3RyaW5nID0gInJldHVybmluZzogXChyZXR1cm5UeXBlU3RyaXBwZWQodHlwZTogdHJ1ZSkpIgogICAgICAgIGd1YXJkIG11bHRpcGxlIGVsc2UgeyByZXR1cm4gcmV0dXJuaW5nIH0KICAgICAgICByZXR1cm4gZnJvbnQgPyAiLCBcKHJldHVybmluZykiIDogIlwocmV0dXJuaW5nKSwgIgogICAgfQogICAgcHJpdmF0ZSBmdW5jIHBhcmFtZXRlcnNGb3JNZXRob2RUeXBlRGVjbGFyYXRpb24oYXZhaWxhYmlsaXR5OiBCb29sID0gZmFsc2UsIHNldDogQm9vbCA9IGZhbHNlKSAtPiBTdHJpbmcgewogICAgICAgIGxldCBnZW5lcmljczogW1N0cmluZ10gPSBnZXRHZW5lcmljcygpCiAgICAgICAgbGV0IHBhcmFtcyA9IHdyYXBwZWRQYXJhbWV0ZXJzLm1hcCB7IHBhcmFtIGluCiAgICAgICAgICAgIGlmIHBhcmFtLmlzR2VuZXJpYyhnZW5lcmljcykgeyByZXR1cm4gcGFyYW0uZ2VuZXJpY1R5cGUgfQogICAgICAgICAgICBpZiBhdmFpbGFiaWxpdHkgeyByZXR1cm4gcGFyYW0udHlwZUVyYXNlZFR5cGUgfQogICAgICAgICAgICByZXR1cm4gcGFyYW0ubmVzdGVkVHlwZQogICAgICAgIH0uam9pbmVkKHNlcGFyYXRvcjogIiwgIikKICAgICAgICBndWFyZCBzZXQgZWxzZSB7IHJldHVybiBwYXJhbXMgfQogICAgICAgIGxldCBuZXdWYWx1ZSA9IFR5cGVXcmFwcGVyKHdyYXBwZWQucmV0dXJuVHlwZU5hbWUpLmlzR2VuZXJpYyhnZW5lcmljcykgPyAiUGFyYW1ldGVyPEdlbmVyaWNBdHRyaWJ1dGU+IiA6IG5lc3RlZFR5cGUKICAgICAgICByZXR1cm4gIlwocGFyYW1zKSwgXChuZXdWYWx1ZSkiCiAgICB9CiAgICBwcml2YXRlIGZ1bmMgcGFyYW1ldGVyc0ZvclByb3h5SW5pdChzZXQ6IEJvb2wgPSBmYWxzZSkgLT4gU3RyaW5nIHsKICAgICAgICBsZXQgZ2VuZXJpY3MgPSBnZXRHZW5lcmljcygpCiAgICAgICAgbGV0IG5ld1ZhbHVlID0gVHlwZVdyYXBwZXIod3JhcHBlZC5yZXR1cm5UeXBlTmFtZSkuaXNHZW5lcmljKGdlbmVyaWNzKSA/ICJuZXdWYWx1ZS53cmFwQXNHZW5lcmljKCkiIDogIm5ld1ZhbHVlIgogICAgICAgIHJldHVybiB3cmFwcGVkUGFyYW1ldGVycy5tYXAgeyAiXCgkMC53cmFwcGVkRm9yUHJveHkoZ2VuZXJpY3MsIGhhc0F2YWlsYWJpbGl0eSkpIiB9LmpvaW5lZChzZXBhcmF0b3I6ICIsICIpICsgKHNldCA/ICIsIFwobmV3VmFsdWUpIiA6ICIiKQogICAgfQogICAgcHJpdmF0ZSBmdW5jIHBhcmFtZXRlcnNGb3JQcm94eVNpZ25hdHVyZShzZXQ6IEJvb2wgPSBmYWxzZSkgLT4gU3RyaW5nIHsKICAgICAgICByZXR1cm4gd3JhcHBlZFBhcmFtZXRlcnMubWFwIHsgIlwoJDAubGFiZWxBbmROYW1lKCkpOiBcKCQwLm5lc3RlZFR5cGUpIiB9LmpvaW5lZChzZXBhcmF0b3I6ICIsICIpICsgKHNldCA/ICIsIHNldCBuZXdWYWx1ZTogXChuZXN0ZWRUeXBlKSIgOiAiIikKICAgIH0KICAgIHByaXZhdGUgZnVuYyBwYXJhbWV0ZXJzRm9yQXNzZXJ0aW9uTmFtZSgpIC0+IFN0cmluZyB7CiAgICAgICAgcmV0dXJuIHdyYXBwZWRQYXJhbWV0ZXJzLm1hcCB7ICJcKCQwLmxhYmVsQW5kTmFtZSgpKSIgfS5qb2luZWQoc2VwYXJhdG9yOiAiLCAiKQogICAgfQogICAgcHJpdmF0ZSBmdW5jIHBhcmFtZXRlcnNGb3JNZXRob2RDYWxsKHNldDogQm9vbCA9IGZhbHNlKSAtPiBTdHJpbmcgewogICAgICAgIGxldCBnZW5lcmljcyA9IGdldEdlbmVyaWNzKCkKICAgICAgICBsZXQgcGFyYW1zID0gd3JhcHBlZFBhcmFtZXRlcnMubWFwIHsgJDAud3JhcHBlZEZvckNhbGxzKGdlbmVyaWNzLCBoYXNBdmFpbGFiaWxpdHkpIH0uam9pbmVkKHNlcGFyYXRvcjogIiwgIikKICAgICAgICBsZXQgcG9zdGZpeCA9IFR5cGVXcmFwcGVyKHdyYXBwZWQucmV0dXJuVHlwZU5hbWUpLmlzR2VuZXJpYyhnZW5lcmljcykgPyAiLndyYXBBc0dlbmVyaWMoKSIgOiAiIgogICAgICAgIHJldHVybiAhc2V0ID8gcGFyYW1zIDogIlwocGFyYW1zKSwgXChuZXN0ZWRUeXBlKS52YWx1ZShuZXdWYWx1ZSlcKHBvc3RmaXgpIgogICAgfQp9CmNsYXNzIFZhcmlhYmxlV3JhcHBlciB7CiAgICBsZXQgdmFyaWFibGU6IFNvdXJjZXJ5UnVudGltZS5WYXJpYWJsZQogICAgbGV0IHNjb3BlOiBTdHJpbmcKICAgIHZhciByZWFkb25seTogQm9vbCB7IHJldHVybiB2YXJpYWJsZS53cml0ZUFjY2Vzcy5pc0VtcHR5IH0KICAgIHZhciBwcml2YXRlUHJvdG90eXBlTmFtZTogU3RyaW5nIHsgcmV0dXJuICJfX3BfXCh2YXJpYWJsZS5uYW1lKSIucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICJgIiwgd2l0aDogIiIpIH0KICAgIHZhciBjYXNlc0NvdW50OiBJbnQgeyByZXR1cm4gcmVhZG9ubHkgPyAxIDogMiB9CgogICAgdmFyIGFjY2Vzc01vZGlmaWVyOiBTdHJpbmcgewogICAgICAgIC8vIFRPRE86IEZpeCBhY2Nlc3MgbGV2ZWxzIGZvciBTd2lmdHlQcm90b3R5cGUKICAgICAgICAvLyBndWFyZCB2YXJpYWJsZS50eXBlPy5hY2Nlc3NMZXZlbCAhPSAiaW50ZXJuYWwiIGVsc2UgeyByZXR1cm4gIiIgfQogICAgICAgIHJldHVybiAicHVibGljICIKICAgIH0KICAgIHZhciBhdHRyaWJ1dGVzOiBTdHJpbmcgewogICAgICAgIGxldCB2YWx1ZSA9IEhlbHBlcnMuZXh0cmFjdEF0dHJpYnV0ZXMoZnJvbTogc2VsZi52YXJpYWJsZS5hdHRyaWJ1dGVzKQogICAgICAgIHJldHVybiB2YWx1ZS5pc0VtcHR5ID8gIlwoYWNjZXNzTW9kaWZpZXIpIiA6ICJcKHZhbHVlKVxuXHRcdFwoYWNjZXNzTW9kaWZpZXIpIgogICAgfQogICAgdmFyIG5vU3R1YkRlZmluZWRNZXNzYWdlOiBTdHJpbmcgeyByZXR1cm4gIlwoc2NvcGUpIC0gc3R1YiB2YWx1ZSBmb3IgXCh2YXJpYWJsZS5uYW1lKSB3YXMgbm90IGRlZmluZWQiIH0KCiAgICB2YXIgZ2V0dGVyOiBTdHJpbmcgewogICAgICAgIGxldCBzdGF0aWNNb2RpZmllciA9IHZhcmlhYmxlLmlzU3RhdGljID8gIlwoc2NvcGUpLiIgOiAiIgogICAgICAgIGxldCByZXR1cm5WYWx1ZSA9IHZhcmlhYmxlLmlzT3B0aW9uYWwgPyAib3B0aW9uYWxHaXZlbkdldHRlclZhbHVlKC5cKHByb3BlcnR5Q2FzZUdldE5hbWUpLCBcIlwobm9TdHViRGVmaW5lZE1lc3NhZ2UpXCIpIiA6ICJnaXZlbkdldHRlclZhbHVlKC5cKHByb3BlcnR5Q2FzZUdldE5hbWUpLCBcIlwobm9TdHViRGVmaW5lZE1lc3NhZ2UpXCIpIgogICAgICAgIHJldHVybiAiXG5cdFx0Z2V0IHtcdFwoc3RhdGljTW9kaWZpZXIpaW52b2NhdGlvbnMuYXBwZW5kKC5cKHByb3BlcnR5Q2FzZUdldE5hbWUpKTsgcmV0dXJuIFwoc3RhdGljTW9kaWZpZXIpXChwcml2YXRlUHJvdG90eXBlTmFtZSkgPz8gXChyZXR1cm5WYWx1ZSkgfSIKICAgIH0KICAgIHZhciBzZXR0ZXI6IFN0cmluZyB7CiAgICAgICAgbGV0IHN0YXRpY01vZGlmaWVyID0gdmFyaWFibGUuaXNTdGF0aWMgPyAiXChzY29wZSkuIiA6ICIiCiAgICAgICAgaWYgcmVhZG9ubHkgewogICAgICAgICAgICByZXR1cm4gIiIKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gIlxuXHRcdHNldCB7XHRcKHN0YXRpY01vZGlmaWVyKWludm9jYXRpb25zLmFwcGVuZCguXChwcm9wZXJ0eUNhc2VTZXROYW1lKSgudmFsdWUobmV3VmFsdWUpKSk7IFwodmFyaWFibGUuaXNTdGF0aWMgPyAiXChzY29wZSkuIiA6ICIiKVwocHJpdmF0ZVByb3RvdHlwZU5hbWUpID0gbmV3VmFsdWUgfSIKICAgICAgICB9CiAgICB9CiAgICB2YXIgcHJvdG90eXBlOiBTdHJpbmcgewogICAgICAgIGxldCBzdGF0aWNNb2RpZmllciA9IHZhcmlhYmxlLmlzU3RhdGljID8gInN0YXRpYyAiIDogIiIKCiAgICAgICAgcmV0dXJuICJcKGF0dHJpYnV0ZXMpXChzdGF0aWNNb2RpZmllcil2YXIgXCh2YXJpYWJsZS5uYW1lKTogXCh2YXJpYWJsZS50eXBlTmFtZS5uYW1lKSB7IiArCiAgICAgICAgICAgICJcKGdldHRlcikiICsKICAgICAgICAgICAgIlwoc2V0dGVyKSIgKwogICAgICAgICJcblx0fSIKICAgIH0KICAgIHZhciBhc3NlcnRpb25OYW1lOiBTdHJpbmcgewogICAgICAgIHZhciByZXN1bHQgPSAiY2FzZSAuXChwcm9wZXJ0eUNhc2VHZXROYW1lKTogcmV0dXJuIFwiW2dldF0gLlwodmFyaWFibGUubmFtZSlcIiIKICAgICAgICBpZiAhcmVhZG9ubHkgewogICAgICAgICAgICByZXN1bHQgKz0gIlxuXHRcdFx0Y2FzZSAuXChwcm9wZXJ0eUNhc2VTZXROYW1lKTogcmV0dXJuIFwiW3NldF0gLlwodmFyaWFibGUubmFtZSlcIiIKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdAogICAgfQoKICAgIHZhciBwcml2YXRlUHJvdG90eXBlOiBTdHJpbmcgewogICAgICAgIGxldCBzdGF0aWNNb2RpZmllciA9IHZhcmlhYmxlLmlzU3RhdGljID8gInN0YXRpYyAiIDogIiIKICAgICAgICB2YXIgdHlwZU5hbWUgPSAiXCh2YXJpYWJsZS50eXBlTmFtZS51bndyYXBwZWRUeXBlTmFtZSkiCiAgICAgICAgbGV0IGlzV3JhcHBlZEluQnJhY2tldHMgPSB0eXBlTmFtZS5oYXNQcmVmaXgoIigiKSAmJiB0eXBlTmFtZS5oYXNTdWZmaXgoIikiKQogICAgICAgIGlmICFpc1dyYXBwZWRJbkJyYWNrZXRzIHsKICAgICAgICAgICAgdHlwZU5hbWUgPSAiKFwodHlwZU5hbWUpKSIKICAgICAgICB9CiAgICAgICAgcmV0dXJuICJwcml2YXRlIFwoc3RhdGljTW9kaWZpZXIpdmFyIFwocHJpdmF0ZVByb3RvdHlwZU5hbWUpOiBcKHR5cGVOYW1lKT8iCiAgICB9CiAgICB2YXIgbmVzdGVkVHlwZTogU3RyaW5nIHsgcmV0dXJuICJcKFR5cGVXcmFwcGVyKHZhcmlhYmxlLnR5cGVOYW1lKS5uZXN0ZWRQYXJhbWV0ZXIpIiB9CgogICAgaW5pdChfIHZhcmlhYmxlOiBTb3VyY2VyeVJ1bnRpbWUuVmFyaWFibGUsIHNjb3BlOiBTdHJpbmcpIHsKICAgICAgICBzZWxmLnZhcmlhYmxlID0gdmFyaWFibGUKICAgICAgICBzZWxmLnNjb3BlID0gc2NvcGUKICAgIH0KCiAgICBmdW5jIGNvbXBhcmVDYXNlcygpIC0+IFN0cmluZyB7CiAgICAgICAgdmFyIHJlc3VsdCA9ICBwcm9wZXJ0eUNhc2VHZXRDb21wYXJlKCkKICAgICAgICBpZiAhcmVhZG9ubHkgewogICAgICAgICAgICByZXN1bHQgKz0gIlxuXHRcdFx0XChwcm9wZXJ0eUNhc2VTZXRDb21wYXJlKCkpIgogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0CiAgICB9CgogICAgZnVuYyBwcm9wZXJ0eUdldCgpIC0+IFN0cmluZyB7CiAgICAgICAgbGV0IHN0YXRpY01vZGlmaWVyID0gdmFyaWFibGUuaXNTdGF0aWMgPyAiU3RhdGljIiA6ICIiCiAgICAgICAgcmV0dXJuICJwdWJsaWMgc3RhdGljIHZhciBcKHZhcmlhYmxlLm5hbWUpOiBcKHN0YXRpY01vZGlmaWVyKVZlcmlmeSB7IHJldHVybiBcKHN0YXRpY01vZGlmaWVyKVZlcmlmeShtZXRob2Q6IC5cKHByb3BlcnR5Q2FzZUdldE5hbWUpKSB9IgogICAgfQoKICAgIGZ1bmMgcHJvcGVydHlTZXQoKSAtPiBTdHJpbmcgewogICAgICAgIGxldCBzdGF0aWNNb2RpZmllciA9IHZhcmlhYmxlLmlzU3RhdGljID8gIlN0YXRpYyIgOiAiIgogICAgICAgIHJldHVybiAicHVibGljIHN0YXRpYyBmdW5jIFwodmFyaWFibGUubmFtZSkoc2V0IG5ld1ZhbHVlOiBcKG5lc3RlZFR5cGUpKSAtPiBcKHN0YXRpY01vZGlmaWVyKVZlcmlmeSB7IHJldHVybiBcKHN0YXRpY01vZGlmaWVyKVZlcmlmeShtZXRob2Q6IC5cKHByb3BlcnR5Q2FzZVNldE5hbWUpKG5ld1ZhbHVlKSkgfSIKICAgIH0KCiAgICB2YXIgcHJvcGVydHlDYXNlR2V0TmFtZTogU3RyaW5nIHsgcmV0dXJuICJwX1wodmFyaWFibGUubmFtZSlfZ2V0Ii5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogImAiLCB3aXRoOiAiIikgfQogICAgZnVuYyBwcm9wZXJ0eUNhc2VHZXQoKSAtPiBTdHJpbmcgewogICAgICAgIHJldHVybiAiY2FzZSBcKHByb3BlcnR5Q2FzZUdldE5hbWUpIgogICAgfQogICAgZnVuYyBwcm9wZXJ0eUNhc2VHZXRDb21wYXJlKCkgLT4gU3RyaW5nIHsKICAgICAgICByZXR1cm4gImNhc2UgKC5cKHByb3BlcnR5Q2FzZUdldE5hbWUpLC5cKHByb3BlcnR5Q2FzZUdldE5hbWUpKTogcmV0dXJuIE1hdGNoZXIuQ29tcGFyaXNvblJlc3VsdC5tYXRjaCIKICAgIH0KICAgIGZ1bmMgcHJvcGVydHlDYXNlR2V0SW50VmFsdWUoKSAtPiBTdHJpbmcgewogICAgICAgIHJldHVybiAiY2FzZSAuXChwcm9wZXJ0eUNhc2VHZXROYW1lKTogcmV0dXJuIDAiCiAgICB9CgogICAgdmFyIHByb3BlcnR5Q2FzZVNldE5hbWU6IFN0cmluZyB7IHJldHVybiAicF9cKHZhcmlhYmxlLm5hbWUpX3NldCIucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICJgIiwgd2l0aDogIiIpIH0KICAgIGZ1bmMgcHJvcGVydHlDYXNlU2V0KCkgLT4gU3RyaW5nIHsKICAgICAgICByZXR1cm4gImNhc2UgXChwcm9wZXJ0eUNhc2VTZXROYW1lKShcKG5lc3RlZFR5cGUpKSIKICAgIH0KICAgIGZ1bmMgcHJvcGVydHlDYXNlU2V0Q29tcGFyZSgpIC0+IFN0cmluZyB7CiAgICAgICAgbGV0IGxoc05hbWUgPSAibGVmdCIKICAgICAgICBsZXQgcmhzTmFtZSA9ICJyaWdodCIKICAgICAgICBsZXQgY29tYXByaXNvbiA9ICJNYXRjaGVyLlBhcmFtZXRlckNvbXBhcmlzb25SZXN1bHQoXChuZXN0ZWRUeXBlKS5jb21wYXJlKGxoczogXChsaHNOYW1lKSwgcmhzOiBcKHJoc05hbWUpLCB3aXRoOiBtYXRjaGVyKSwgXChsaHNOYW1lKSwgXChyaHNOYW1lKSwgXCJuZXdWYWx1ZVwiKSIKICAgICAgICBsZXQgcmVzdWx0ID0gIk1hdGNoZXIuQ29tcGFyaXNvblJlc3VsdChbXChjb21hcHJpc29uKV0pIgogICAgICAgIHJldHVybiAiY2FzZSAoLlwocHJvcGVydHlDYXNlU2V0TmFtZSkobGV0IGxlZnQpLC5cKHByb3BlcnR5Q2FzZVNldE5hbWUpKGxldCByaWdodCkpOiByZXR1cm4gXChyZXN1bHQpIgogICAgfQogICAgZnVuYyBwcm9wZXJ0eUNhc2VTZXRJbnRWYWx1ZSgpIC0+IFN0cmluZyB7CiAgICAgICAgcmV0dXJuICJjYXNlIC5cKHByb3BlcnR5Q2FzZVNldE5hbWUpKGxldCBuZXdWYWx1ZSk6IHJldHVybiBuZXdWYWx1ZS5pbnRWYWx1ZSIKICAgIH0KCiAgICAvLyBHaXZlbgogICAgZnVuYyBnaXZlbkNvbnN0cnVjdG9yTmFtZShwcmVmaXg6IFN0cmluZyA9ICIiKSAtPiBTdHJpbmcgewogICAgICAgIHJldHVybiAiXChhdHRyaWJ1dGVzKXN0YXRpYyBmdW5jIFwodmFyaWFibGUubmFtZSkoZ2V0dGVyIGRlZmF1bHRWYWx1ZTogXChUeXBlV3JhcHBlcih2YXJpYWJsZS50eXBlTmFtZSkuc3RyaXBwZWQpLi4uKSAtPiBcKHByZWZpeClQcm9wZXJ0eVN0dWIiCiAgICB9CgogICAgZnVuYyBnaXZlbkNvbnN0cnVjdG9yKHByZWZpeDogU3RyaW5nID0gIiIpIC0+IFN0cmluZyB7CiAgICAgICAgcmV0dXJuICJyZXR1cm4gXChwcmVmaXgpR2l2ZW4obWV0aG9kOiAuXChwcm9wZXJ0eUNhc2VHZXROYW1lKSwgcHJvZHVjdHM6IGRlZmF1bHRWYWx1ZS5tYXAoeyBTdHViUHJvZHVjdC5yZXR1cm4oJDAgYXMgQW55KSB9KSkiCiAgICB9Cn0KXyU+CjwlIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBTRVRVUCAtJT48JV8gLSU+CjwlXyB2YXIgYWxsID0gdHlwZXMuYWxsCiAgICBhbGwgKz0gdHlwZXMucHJvdG9jb2xzLm1hcCB7ICQwIH0KICAgIGFsbCArPSB0eXBlcy5wcm90b2NvbENvbXBvc2l0aW9ucy5tYXAgeyAkMCB9CiAgICB2YXIgbW9ja2VkQ291bnQgPSAwCi0lPgoKPCVfIGZvciB0eXBlIGluIGFsbCB7IC0lPjwlXyAtJT4KPCVfIGxldCBhdXRvTW9ja2FibGU6IEJvb2wgPSB0eXBlLmluaGVyaXRlZFR5cGVzLmNvbnRhaW5zKCJBdXRvTW9ja2FibGUiKSB8fCB0eXBlLmFubm90YXRpb25zWyJBdXRvTW9ja2FibGUiXSAhPSBuaWwKICAgIGxldCBwcm90b2NvbFRvRGVjb3JhdGUgPSB0eXBlcy5wcm90b2NvbHMuZmlyc3Qod2hlcmU6IHsgJDAubmFtZSA9PSAodHlwZS5hbm5vdGF0aW9uc1sibW9jayJdIGFzPyBTdHJpbmcpIH0pCiAgICBsZXQgaW5saW5lTW9ja2FibGUgPSBwcm90b2NvbFRvRGVjb3JhdGUgIT0gbmlsCiAgICBndWFyZCBsZXQgYVByb3RvY29sID0gYXV0b01vY2thYmxlID8gdHlwZSA6IHByb3RvY29sVG9EZWNvcmF0ZSBlbHNlIHsgY29udGludWUgfQogICAgbW9ja2VkQ291bnQgKz0gMQoKICAgIGxldCBhc3NvY2lhdGVkVHlwZXM6IFtTdHJpbmddPyA9IEhlbHBlcnMuZXh0cmFjdEFzc29jaWF0ZWRUeXBlcyhmcm9tOiBhUHJvdG9jb2wpCiAgICBsZXQgYXR0cmlidXRlczogU3RyaW5nID0gSGVscGVycy5leHRyYWN0QXR0cmlidXRlcyhmcm9tOiB0eXBlLmF0dHJpYnV0ZXMpCiAgICBsZXQgdHlwZUFsaWFzZXM6IFtTdHJpbmddID0gSGVscGVycy5leHRyYWN0VHlwZWFsaWFzZXMoZnJvbTogYVByb3RvY29sKQogICAgbGV0IGdlbmVyaWNUeXBlc01vZGlmaWVyOiBTdHJpbmcgPSBIZWxwZXJzLmV4dHJhY3RHZW5lcmljVHlwZXNNb2RpZmllcihhc3NvY2lhdGVkVHlwZXMpCiAgICBsZXQgZ2VuZXJpY1R5cGVzQ29uc3RyYWludHM6IFN0cmluZyA9IEhlbHBlcnMuZXh0cmFjdEdlbmVyaWNUeXBlc0NvbnN0cmFpbnRzKGFzc29jaWF0ZWRUeXBlcykKICAgIGxldCBhbGxTdWJzY3JpcHRzID0gYVByb3RvY29sLmFsbFN1YnNjcmlwdHMKICAgIGxldCBhbGxWYXJpYWJsZXMgPSB1bmlxdWVzKHZhcmlhYmxlczogYVByb3RvY29sLmFsbFZhcmlhYmxlcy5maWx0ZXIoeyAhJDAuaXNTdGF0aWMgfSkpCiAgICBsZXQgY29udGFpbnNWYXJpYWJsZXMgPSAhYWxsVmFyaWFibGVzLmlzRW1wdHkKICAgIGxldCBhbGxTdGF0aWNWYXJpYWJsZXMgPSB1bmlxdWVzKHZhcmlhYmxlczogYVByb3RvY29sLmFsbFZhcmlhYmxlcy5maWx0ZXIoeyAkMC5pc1N0YXRpYyB9KSkKICAgIGxldCBjb250YWluc1N0YXRpY1ZhcmlhYmxlcyA9ICFhbGxTdGF0aWNWYXJpYWJsZXMuaXNFbXB0eQogICAgbGV0IGFsbE1ldGhvZHMgPSB1bmlxdWVzKG1ldGhvZHM6IGFQcm90b2NvbC5hbGxNZXRob2RzLmZpbHRlcih7ICEkMC5pc1N0YXRpYyB8fCAkMC5pc0luaXRpYWxpemVyIH0pKQogICAgbGV0IHNlbGZDb25zdHJhaW5lZCA9IGFsbE1ldGhvZHMubWFwKHdyYXBNZXRob2QpLmNvbnRhaW5zKHdoZXJlOiB7ICQwLnJldHVybnNHZW5lcmljQ29uc3RyYWluZWRUb1NlbGYgfHwgJDAucGFyYW1ldGVyc0NvbnRhaW5zU2VsZiB9KQogICAgbGV0IGFjY2Vzc01vZGlmaWVyOiBTdHJpbmcgPSBzZWxmQ29uc3RyYWluZWQgPyAicHVibGljIGZpbmFsIiA6ICJvcGVuIgogICAgQ3VycmVudC5hY2Nlc3NNb2RpZmllciA9IGFjY2Vzc01vZGlmaWVyIC8vIFRPRE86IFRlbXBvcmFyeSB3b3JrYXJvdW5kIGZvciBhY2Nlc3MgbW9kaWZpZXJzCiAgICBsZXQgaW5oZXJpdEZyb21OU09iamVjdCA9IHR5cGUuYW5ub3RhdGlvbnNbIk9iamNQcm90b2NvbCJdICE9IG5pbCB8fCBhdHRyaWJ1dGVzLmNvbnRhaW5zKCJAb2JqYyIpCiAgICBsZXQgYWxsTWV0aG9kc0Zvck1ldGhvZFR5cGUgPSB1bmlxdWVzV2l0aG91dEdlbmVyaWNDb25zdHJhaW50cyhtZXRob2RzOiBhUHJvdG9jb2wuYWxsTWV0aG9kcy5maWx0ZXIoeyAhJDAuaXNTdGF0aWMgfSkpCiAgICBsZXQgYWxsU3RhdGljTWV0aG9kcyA9IHVuaXF1ZXMobWV0aG9kczogYVByb3RvY29sLmFsbE1ldGhvZHMuZmlsdGVyKHsgJDAuaXNTdGF0aWMgJiYgISQwLmlzSW5pdGlhbGl6ZXIgfSkpCiAgICBsZXQgYWxsU3RhdGljTWV0aG9kc0Zvck1ldGhvZFR5cGUgPSB1bmlxdWVzV2l0aG91dEdlbmVyaWNDb25zdHJhaW50cyhtZXRob2RzOiBhUHJvdG9jb2wuYWxsTWV0aG9kcy5maWx0ZXIoeyAkMC5pc1N0YXRpYyB9KSkKICAgIGxldCBjb25mb3Jtc1RvU3RhdGljTW9jayA9ICFhbGxTdGF0aWNNZXRob2RzLmlzRW1wdHkgfHwgIWFsbFN0YXRpY1ZhcmlhYmxlcy5pc0VtcHR5CiAgICBsZXQgY29uZm9ybXNUb01vY2sgPSAhYWxsTWV0aG9kcy5pc0VtcHR5IHx8ICFhbGxWYXJpYWJsZXMuaXNFbXB0eSAtJT48JV8gLSU+PCVfIC0lPgo8JV8gaWYgYXV0b01vY2thYmxlIHsgLSU+Ci8vIE1BUks6IC0gPCU9IHR5cGUubmFtZSAlPgo8JT0gYXR0cmlidXRlcyAlPgo8JT0gYWNjZXNzTW9kaWZpZXIgJT4gY2xhc3MgPCU9IHR5cGUubmFtZSAlPjwlPSBtb2NrVHlwZU5hbWUgJT48JT0gZ2VuZXJpY1R5cGVzTW9kaWZpZXIgJT46PCU9IGluaGVyaXRGcm9tTlNPYmplY3QgPyAiIE5TT2JqZWN0LCIgOiAiIiAlPiA8JT0gdHlwZS5uYW1lICU+LCBNb2NrPCU9IGNvbmZvcm1zVG9TdGF0aWNNb2NrID8gIiwgU3RhdGljTW9jayIgOiAiIiAlPjwlPSBnZW5lcmljVHlwZXNDb25zdHJhaW50cyAlPiB7CiAgICBwdWJsaWMgaW5pdChzZXF1ZW5jaW5nIHNlcXVlbmNpbmdQb2xpY3k6IFNlcXVlbmNpbmdQb2xpY3kgPSAubGFzdFdyaXR0ZW5SZXNvbHZlZEZpcnN0LCBzdHViYmluZyBzdHViYmluZ1BvbGljeTogU3R1YmJpbmdQb2xpY3kgPSAud3JhcCwgZmlsZTogU3RhdGljU3RyaW5nID0gI2ZpbGUsIGxpbmU6IFVJbnQgPSAjbGluZSkgewogICAgICAgIFN3aWZ0eU1vY2t5VGVzdE9ic2VydmVyLnNldHVwKCkKICAgICAgICBzZWxmLnNlcXVlbmNpbmdQb2xpY3kgPSBzZXF1ZW5jaW5nUG9saWN5CiAgICAgICAgc2VsZi5zdHViYmluZ1BvbGljeSA9IHN0dWJiaW5nUG9saWN5CiAgICAgICAgc2VsZi5maWxlID0gZmlsZQogICAgICAgIHNlbGYubGluZSA9IGxpbmUKICAgIH0KCjwlXyB9IGVsc2UgeyAtJT4KLy8gc291cmNlcnk6aW5saW5lOmF1dG86PCU9IHR5cGUubmFtZSAlPi5hdXRvTW9ja2VkCjwlXyB9IC0lPgo8JSMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gTUFJTiBDTEFTUyAtJT48JV8gLSU+CiAgPCUjID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IE1PQ0sgSU5URVJOQUxTIC0lPjwlXyAtJT4KICAgIHZhciBtYXRjaGVyOiBNYXRjaGVyID0gTWF0Y2hlci5kZWZhdWx0CiAgICB2YXIgc3R1YmJpbmdQb2xpY3k6IFN0dWJiaW5nUG9saWN5ID0gLndyYXAKICAgIHZhciBzZXF1ZW5jaW5nUG9saWN5OiBTZXF1ZW5jaW5nUG9saWN5ID0gLmxhc3RXcml0dGVuUmVzb2x2ZWRGaXJzdAoKICAgIHByaXZhdGUgdmFyIHF1ZXVlID0gRGlzcGF0Y2hRdWV1ZShsYWJlbDogImNvbS5zd2lmdHltb2NreS5pbnZvY2F0aW9ucyIsIHFvczogLnVzZXJJbnRlcmFjdGl2ZSkKICAgIHByaXZhdGUgdmFyIGludm9jYXRpb25zOiBbTWV0aG9kVHlwZV0gPSBbXQogICAgcHJpdmF0ZSB2YXIgbWV0aG9kUmV0dXJuVmFsdWVzOiBbR2l2ZW5dID0gW10KICAgIHByaXZhdGUgdmFyIG1ldGhvZFBlcmZvcm1WYWx1ZXM6IFtQZXJmb3JtXSA9IFtdCiAgICBwcml2YXRlIHZhciBmaWxlOiBTdGF0aWNTdHJpbmc/CiAgICBwcml2YXRlIHZhciBsaW5lOiBVSW50PwoKICAgIHB1YmxpYyB0eXBlYWxpYXMgUHJvcGVydHlTdHViID0gR2l2ZW4KICAgIHB1YmxpYyB0eXBlYWxpYXMgTWV0aG9kU3R1YiA9IEdpdmVuCiAgICBwdWJsaWMgdHlwZWFsaWFzIFN1YnNjcmlwdFN0dWIgPSBHaXZlbgogICAgPCVfIGZvciB0eXBlQWxpYXMgaW4gdHlwZUFsaWFzZXMgeyAtJT4KICAgIHB1YmxpYyB0eXBlYWxpYXMgPCU9IHR5cGVBbGlhcyAlPgogICAgPCVfIH0gJT4gPCVfIC0lPgoKICAgIC8vLyBDb252ZW5pZW5jZSBtZXRob2QgLSBjYWxsIHNldHVwTW9jaygpIHRvIGV4dGVuZCBkZWJ1ZyBpbmZvcm1hdGlvbiB3aGVuIGZhaWx1cmUgb2NjdXJzCiAgICBwdWJsaWMgZnVuYyBzZXR1cE1vY2soZmlsZTogU3RhdGljU3RyaW5nID0gI2ZpbGUsIGxpbmU6IFVJbnQgPSAjbGluZSkgewogICAgICAgIHNlbGYuZmlsZSA9IGZpbGUKICAgICAgICBzZWxmLmxpbmUgPSBsaW5lCiAgICB9CgogICAgLy8vIENsZWFyIG1vY2sgaW50ZXJuYWxzLiBZb3UgY2FuIHNwZWNpZnkgd2hhdCB0byByZXNldCAoaW52b2NhdGlvbnMgYWthIHZlcmlmeSwgZ2l2ZW5zIG9yIHBlcmZvcm1zKSBvciBsZWF2ZSBpdCBlbXB0eSB0byBjbGVhciBhbGwgbW9jayBpbnRlcm5hbHMKICAgIHB1YmxpYyBmdW5jIHJlc2V0TW9jayhfIHNjb3BlczogTW9ja1Njb3BlLi4uKSB7CiAgICAgICAgbGV0IHNjb3BlczogW01vY2tTY29wZV0gPSBzY29wZXMuaXNFbXB0eSA/IFsuaW52b2NhdGlvbiwgLmdpdmVuLCAucGVyZm9ybV0gOiBzY29wZXMKICAgICAgICBpZiBzY29wZXMuY29udGFpbnMoLmludm9jYXRpb24pIHsgaW52b2NhdGlvbnMgPSBbXSB9CiAgICAgICAgaWYgc2NvcGVzLmNvbnRhaW5zKC5naXZlbikgeyBtZXRob2RSZXR1cm5WYWx1ZXMgPSBbXSB9CiAgICAgICAgaWYgc2NvcGVzLmNvbnRhaW5zKC5wZXJmb3JtKSB7IG1ldGhvZFBlcmZvcm1WYWx1ZXMgPSBbXSB9CiAgICB9CiAgICA8JV8gLSU+CiAgPCUjID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IFNUQVRJQyBNT0NLIElOVEVSTkFMUyAtJT48JV8gLSU+CiAgICA8JV8gaWYgY29uZm9ybXNUb1N0YXRpY01vY2sgeyAtJT4KICAgIHN0YXRpYyB2YXIgbWF0Y2hlcjogTWF0Y2hlciA9IE1hdGNoZXIuZGVmYXVsdAogICAgc3RhdGljIHZhciBzdHViYmluZ1BvbGljeTogU3R1YmJpbmdQb2xpY3kgPSAud3JhcAogICAgc3RhdGljIHZhciBzZXF1ZW5jaW5nUG9saWN5OiBTZXF1ZW5jaW5nUG9saWN5ID0gLmxhc3RXcml0dGVuUmVzb2x2ZWRGaXJzdAogICAgc3RhdGljIHByaXZhdGUgdmFyIHF1ZXVlID0gRGlzcGF0Y2hRdWV1ZShsYWJlbDogImNvbS5zd2lmdHltb2NreS5pbnZvY2F0aW9ucy5zdGF0aWMiLCBxb3M6IC51c2VySW50ZXJhY3RpdmUpCiAgICBzdGF0aWMgcHJpdmF0ZSB2YXIgaW52b2NhdGlvbnM6IFtTdGF0aWNNZXRob2RUeXBlXSA9IFtdCiAgICBzdGF0aWMgcHJpdmF0ZSB2YXIgbWV0aG9kUmV0dXJuVmFsdWVzOiBbU3RhdGljR2l2ZW5dID0gW10KICAgIHN0YXRpYyBwcml2YXRlIHZhciBtZXRob2RQZXJmb3JtVmFsdWVzOiBbU3RhdGljUGVyZm9ybV0gPSBbXQogICAgcHVibGljIHR5cGVhbGlhcyBTdGF0aWNQcm9wZXJ0eVN0dWIgPSBTdGF0aWNHaXZlbgogICAgcHVibGljIHR5cGVhbGlhcyBTdGF0aWNNZXRob2RTdHViID0gU3RhdGljR2l2ZW4KCiAgICAvLy8gQ2xlYXIgbW9jayBpbnRlcm5hbHMuIFlvdSBjYW4gc3BlY2lmeSB3aGF0IHRvIHJlc2V0IChpbnZvY2F0aW9ucyBha2EgdmVyaWZ5LCBnaXZlbnMgb3IgcGVyZm9ybXMpIG9yIGxlYXZlIGl0IGVtcHR5IHRvIGNsZWFyIGFsbCBtb2NrIGludGVybmFscwogICAgcHVibGljIHN0YXRpYyBmdW5jIHJlc2V0TW9jayhfIHNjb3BlczogTW9ja1Njb3BlLi4uKSB7CiAgICAgICAgbGV0IHNjb3BlczogW01vY2tTY29wZV0gPSBzY29wZXMuaXNFbXB0eSA/IFsuaW52b2NhdGlvbiwgLmdpdmVuLCAucGVyZm9ybV0gOiBzY29wZXMKICAgICAgICBpZiBzY29wZXMuY29udGFpbnMoLmludm9jYXRpb24pIHsgaW52b2NhdGlvbnMgPSBbXSB9CiAgICAgICAgaWYgc2NvcGVzLmNvbnRhaW5zKC5naXZlbikgeyBtZXRob2RSZXR1cm5WYWx1ZXMgPSBbXSB9CiAgICAgICAgaWYgc2NvcGVzLmNvbnRhaW5zKC5wZXJmb3JtKSB7IG1ldGhvZFBlcmZvcm1WYWx1ZXMgPSBbXSB9CiAgICB9CiAgICA8JV8gIH0gLSU+CgogIDwlIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBWQVJJQUJMRVMgLSU+PCVfIC0lPgogICAgPCVfIGZvciB2YXJpYWJsZSBpbiBhbGxWYXJpYWJsZXMgeyAtJT4KICAgIDwlXyBpZiBhdXRvTW9ja2FibGUgeyAtJT4KICAgIDwlPSBzdHViUHJvcGVydHkodmFyaWFibGUsIlwodHlwZS5uYW1lKVwobW9ja1R5cGVOYW1lKSIpICU+CiAgICA8JV8gfSBlbHNlIHsgJT4KICAgIDwlPSBzdHViUHJvcGVydHkodmFyaWFibGUsIlwodHlwZS5uYW1lKSIpICU+CiAgICA8JV8gfSAlPgogICAgPCVfIH0gJT4gPCVfIC0lPgoKICA8JSMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gU1RBVElDIFZBUklBQkxFUyAtJT48JV8gLSU+CiAgICA8JV8gZm9yIHZhcmlhYmxlIGluIGFsbFN0YXRpY1ZhcmlhYmxlcyB7IC0lPgogICAgPCVfIGlmIGF1dG9Nb2NrYWJsZSB7IC0lPgogICAgPCU9IHN0dWJQcm9wZXJ0eSh2YXJpYWJsZSwiXCh0eXBlLm5hbWUpXChtb2NrVHlwZU5hbWUpIikgJT4KICAgIDwlXyB9IGVsc2UgeyAlPgogICAgPCU9IHN0dWJQcm9wZXJ0eSh2YXJpYWJsZSwiXCh0eXBlLm5hbWUpIikgJT4KICAgIDwlXyB9ICU+CiAgICA8JV8gfSAlPiA8JV8gLSU+CgogIDwlIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBNRVRIT0QgUkVHSVNUUkFUSU9OUyAtJT48JV8gLSU+CiAgICA8JV8gTWV0aG9kV3JhcHBlci5jbGVhcigpIC0lPgogICAgPCVfIFN1YnNjcmlwdFdyYXBwZXIuY2xlYXIoKSAtJT4KICAgIDwlXyBpZiBhdXRvTW9ja2FibGUgeyAtJT4KICAgIDwlXyBDdXJyZW50LnNlbGZUeXBlID0gIlwodHlwZS5uYW1lKVwobW9ja1R5cGVOYW1lKVwoZ2VuZXJpY1R5cGVzTW9kaWZpZXIpIiAtJT4KICAgIDwlXyB9IGVsc2UgeyAlPgogICAgPCVfIEN1cnJlbnQuc2VsZlR5cGUgPSAiXCh0eXBlLm5hbWUpXChtb2NrVHlwZU5hbWUpXChnZW5lcmljVHlwZXNNb2RpZmllcikiIC0lPgogICAgPCVfIH0gJT4KICAgIDwlXyBsZXQgd3JhcHBlZFN1YnNjcmlwdHMgPSBhbGxTdWJzY3JpcHRzLm1hcCh3cmFwU3Vic2NyaXB0KSAtJT4KICAgIDwlXyBsZXQgd3JhcHBlZE1ldGhvZHMgPSBhbGxNZXRob2RzLm1hcCh3cmFwTWV0aG9kKS5maWx0ZXIoeyAkMC53cmFwcGVkSW5NZXRob2RUeXBlKCkgfSkgLSU+CiAgICA8JV8gbGV0IHdyYXBwZWRWYXJpYWJsZXMgPSBhbGxWYXJpYWJsZXMubWFwKGp1c3RXcmFwKSAtJT4KICAgIDwlXyBsZXQgd3JhcHBlZE1ldGhvZHNGb3JNZXRob2RUeXBlID0gYWxsTWV0aG9kc0Zvck1ldGhvZFR5cGUubWFwKHdyYXBNZXRob2QpLmZpbHRlcih7ICQwLndyYXBwZWRJbk1ldGhvZFR5cGUoKSB9KSAtJT4KICAgIDwlXyBsZXQgd3JhcHBlZEluaXRpYWxpemVycyA9IGFsbE1ldGhvZHMubWFwKHdyYXBNZXRob2QpLmZpbHRlcih7ICQwLm1ldGhvZC5pc0luaXRpYWxpemVyIH0pIC0lPgogICAgPCVfIGxldCB3cmFwcGVkU3RhdGljTWV0aG9kcyA9IGFsbFN0YXRpY01ldGhvZHMubWFwKHdyYXBNZXRob2QpLmZpbHRlcih7ICQwLndyYXBwZWRJbk1ldGhvZFR5cGUoKSB9KSAtJT4KICAgIDwlXyBsZXQgd3JhcHBlZFN0YXRpY1ZhcmlhYmxlcyA9IGFsbFN0YXRpY1ZhcmlhYmxlcy5tYXAoanVzdFdyYXApIC0lPgogICAgPCVfIGxldCB3cmFwcGVkU3RhdGljTWV0aG9kc0Zvck1ldGhvZFR5cGUgPSBhbGxTdGF0aWNNZXRob2RzRm9yTWV0aG9kVHlwZS5tYXAod3JhcE1ldGhvZCkuZmlsdGVyKHsgJDAud3JhcHBlZEluTWV0aG9kVHlwZSgpIH0pIC0lPgogICAgPCVfIGZvciB2YXJpYWJsZSBpbiBhbGxWYXJpYWJsZXMgeyBwcm9wZXJ0eVJlZ2lzdGVyKHZhcmlhYmxlKSB9IC0lPgogICAgPCVfIGZvciB2YXJpYWJsZSBpbiBhbGxTdGF0aWNWYXJpYWJsZXMgeyBwcm9wZXJ0eVJlZ2lzdGVyKHZhcmlhYmxlKSB9IC0lPgogICAgPCVfIGZvciBtZXRob2QgaW4gd3JhcHBlZE1ldGhvZHMgeyBtZXRob2QucmVnaXN0ZXIoKSB9IC0lPgogICAgPCVfIGZvciB3cmFwcGVkIGluIHdyYXBwZWRTdWJzY3JpcHRzIHsgd3JhcHBlZC5yZWdpc3RlcigpIH0gLSU+CiAgICA8JV8gZm9yIG1ldGhvZCBpbiB3cmFwcGVkU3RhdGljTWV0aG9kcyB7IG1ldGhvZC5yZWdpc3RlcigpIH0gLSU+PCVfIC0lPgogICAgPCVfIGxldCB2YXJpYWJsZUNhc2VzQ291bnQ6IEludCA9IHdyYXBwZWRWYXJpYWJsZXMucmVkdWNlKDApIHsgcmV0dXJuICQwICsgJDEuY2FzZXNDb3VudCB9IC0lPjwlXyAtJT4KICAgIDwlXyBsZXQgc3Vic2NyaXB0c0Nhc2VzQ291bnQ6IEludCA9IHdyYXBwZWRTdWJzY3JpcHRzLnJlZHVjZSgwKSB7IHJldHVybiAkMCArICQxLmNhc2VzQ291bnQgfSAtJT48JV8gLSU+CiAgICA8JV8gbGV0IHN0YXRpY1ZhcmlhYmxlQ2FzZXNDb3VudDogSW50ID0gd3JhcHBlZFN0YXRpY1ZhcmlhYmxlcy5yZWR1Y2UoMCkgeyByZXR1cm4gJDAgKyAkMS5jYXNlc0NvdW50IH0gLSU+PCVfIC0lPgoKICA8JSMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gU1RBVElDIFNUVUJTIC0lPjwlXyAtJT4KICAgIDwlXyBmb3IgbWV0aG9kIGluIHdyYXBwZWRTdGF0aWNNZXRob2RzIHsgLSU+CiAgICA8JT0gbWV0aG9kLmZ1bmN0aW9uUHJvdG90eXBlIF8lPiB7CiAgICAgICAgPCU9IG1ldGhvZC5zdHViQm9keSgpIF8lPgogICAgfQoKICAgIDwlXyB9ICU+PCVfIC0lPgogICAgPCVfIC0lPgogIDwlIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBJTklUSUFMSVpFUlMgLSU+PCVfIC0lPgogICAgPCVfIGZvciBtZXRob2QgaW4gd3JhcHBlZEluaXRpYWxpemVycyB7IC0lPgogICAgPCU9IG1ldGhvZC5mdW5jdGlvblByb3RvdHlwZSBfJT4geyB9CgogICAgPCVfIH0gLSU+PCVfIC0lPgogICAgPCVfIC0lPjwlXyAtJT4KICA8JSMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gU1RVQlMgLSU+PCVfIC0lPgogICAgPCVfIGZvciBtZXRob2QgaW4gd3JhcHBlZE1ldGhvZHMgeyAtJT4KICAgIDwlPSBtZXRob2QuZnVuY3Rpb25Qcm90b3R5cGUgXyU+IHsKICAgICAgICA8JT0gbWV0aG9kLnN0dWJCb2R5KCkgXyU+CiAgICB9CgogICAgPCVfIH0gLSU+CiAgICA8JV8gZm9yIHdyYXBwZWQgaW4gd3JhcHBlZFN1YnNjcmlwdHMgeyAtJT4KICAgIDwlPSB3cmFwcGVkLnN1YnNjcmlwdENhbGwoKSBfJT4KCiAgICA8JV8gfSAtJT4KICA8JSMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gU1RBVElDIE1FVEhPRCBUWVBFIC0lPjwlXyAtJT4KICAgIDwlXyBpZiBjb25mb3Jtc1RvU3RhdGljTW9jayB7IC0lPgogICAgZmlsZXByaXZhdGUgZW51bSBTdGF0aWNNZXRob2RUeXBlIHsKICAgIDwlXyBmb3IgbWV0aG9kIGluIHdyYXBwZWRTdGF0aWNNZXRob2RzRm9yTWV0aG9kVHlwZSB7IC0lPgogICAgICAgIDwlPSBtZXRob2QubWV0aG9kVHlwZURlY2xhcmF0aW9uV2l0aFBhcmFtZXRlcnMoKSBfJT4KICAgIDwlXyAgfSAlPiA8JV8gZm9yIHZhcmlhYmxlIGluIGFsbFN0YXRpY1ZhcmlhYmxlcyB7IC0lPgogICAgICAgIDwlPSBwcm9wZXJ0eU1ldGhvZFR5cGVzKHZhcmlhYmxlKSAlPgogICAgPCVfIH0gJT4gPCVfICU+CiAgICA8JV8gLSU+CiAgICAgICAgc3RhdGljIGZ1bmMgY29tcGFyZVBhcmFtZXRlcnMobGhzOiBTdGF0aWNNZXRob2RUeXBlLCByaHM6IFN0YXRpY01ldGhvZFR5cGUsIG1hdGNoZXI6IE1hdGNoZXIpIC0+IE1hdGNoZXIuQ29tcGFyaXNvblJlc3VsdCB7CiAgICAgICAgICAgIHN3aXRjaCAobGhzLCByaHMpIHsgPCVfIGZvciBtZXRob2QgaW4gd3JhcHBlZFN0YXRpY01ldGhvZHNGb3JNZXRob2RUeXBlIHsgJT4KICAgICAgICAgICAgPCU9IG1ldGhvZC5lcXVhbENhc2VzKCkgJT4KICAgICAgICAgICAgPCVfIH0gJT4gPCVfIGZvciB2YXJpYWJsZSBpbiB3cmFwcGVkU3RhdGljVmFyaWFibGVzIHsgLSU+CiAgICAgICAgICAgIDwlPSB2YXJpYWJsZS5jb21wYXJlQ2FzZXMoKSAlPgogICAgICAgICAgICA8JV8gfSAlPiA8JV8gLSU+IDwlXyBpZiB3cmFwcGVkU3RhdGljTWV0aG9kcy5jb3VudCArIHN0YXRpY1ZhcmlhYmxlQ2FzZXNDb3VudCA+IDEgeyAtJT4KICAgICAgICAgICAgZGVmYXVsdDogcmV0dXJuIC5ub25lCiAgICAgICAgICAgIDwlXyB9IC0lPgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgPCVfICU+CiAgICAgICAgZnVuYyBpbnRWYWx1ZSgpIC0+IEludCB7CiAgICAgICAgICAgIHN3aXRjaCBzZWxmIHsgPCVfIGZvciBtZXRob2QgaW4gd3JhcHBlZFN0YXRpY01ldGhvZHNGb3JNZXRob2RUeXBlIHsgJT4KICAgICAgICAgICAgICAgIDwlPSBtZXRob2QuaW50VmFsdWVDYXNlIC0lPjwlIH0gJT4KICAgICAgICAgICAgICAgIDwlXyBmb3IgdmFyaWFibGUgaW4gYWxsU3RhdGljVmFyaWFibGVzIHsgLSU+CiAgICAgICAgICAgICAgICA8JT0gcHJvcGVydHlNZXRob2RUeXBlc0ludFZhbHVlKHZhcmlhYmxlKSAlPgogICAgICAgICAgICAgICAgPCVfIH0gJT4gPCVfIC0lPgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZ1bmMgYXNzZXJ0aW9uTmFtZSgpIC0+IFN0cmluZyB7CiAgICAgICAgICAgIHN3aXRjaCBzZWxmIHsgPCVfIGZvciBtZXRob2QgaW4gd3JhcHBlZFN0YXRpY01ldGhvZHNGb3JNZXRob2RUeXBlIHsgJT4KICAgICAgICAgICAgPCU9IG1ldGhvZC5hc3NlcnRpb25OYW1lIC0lPjwlIH0gJT4KICAgICAgICAgICAgPCVfIGZvciB2YXJpYWJsZSBpbiB3cmFwcGVkU3RhdGljVmFyaWFibGVzIHsgLSU+CiAgICAgICAgICAgIDwlPSB2YXJpYWJsZS5hc3NlcnRpb25OYW1lICU+CiAgICAgICAgICAgIDwlXyB9ICU+CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgb3BlbiBjbGFzcyBTdGF0aWNHaXZlbjogU3R1YmJlZE1ldGhvZCB7CiAgICAgICAgZmlsZXByaXZhdGUgdmFyIG1ldGhvZDogU3RhdGljTWV0aG9kVHlwZQoKICAgICAgICBwcml2YXRlIGluaXQobWV0aG9kOiBTdGF0aWNNZXRob2RUeXBlLCBwcm9kdWN0czogW1N0dWJQcm9kdWN0XSkgewogICAgICAgICAgICBzZWxmLm1ldGhvZCA9IG1ldGhvZAogICAgICAgICAgICBzdXBlci5pbml0KHByb2R1Y3RzKQogICAgICAgIH0KCiAgICAgICAgPCVfIGZvciB2YXJpYWJsZSBpbiBhbGxTdGF0aWNWYXJpYWJsZXMgeyAtJT4KICAgICAgICA8JT0gd3JhcFByb3BlcnR5KHZhcmlhYmxlKS5naXZlbkNvbnN0cnVjdG9yTmFtZShwcmVmaXg6ICJTdGF0aWMiKSAtJT4gewogICAgICAgICAgICA8JT0gd3JhcFByb3BlcnR5KHZhcmlhYmxlKS5naXZlbkNvbnN0cnVjdG9yKHByZWZpeDogIlN0YXRpYyIpIF8lPgogICAgICAgIH0KICAgICAgICA8JV8gfSAlPiA8JV8gJT4KICAgICAgICA8JV8gZm9yIG1ldGhvZCBpbiB3cmFwcGVkU3RhdGljTWV0aG9kc0Zvck1ldGhvZFR5cGUuZmlsdGVyKHsgISQwLm1ldGhvZC5yZXR1cm5UeXBlTmFtZS5pc1ZvaWQgJiYgISQwLm1ldGhvZC5pc0luaXRpYWxpemVyIH0pIHsgLSU+CiAgICAgICAgPCU9IG1ldGhvZC5naXZlbkNvbnN0cnVjdG9yTmFtZShwcmVmaXg6ICJTdGF0aWMiKSAtJT4gewogICAgICAgICAgICA8JT0gbWV0aG9kLmdpdmVuQ29uc3RydWN0b3IocHJlZml4OiAiU3RhdGljIikgXyU+CiAgICAgICAgfQogICAgICAgIDwlXyB9IC0lPgogICAgICAgIDwlXyBmb3IgbWV0aG9kIGluIHdyYXBwZWRTdGF0aWNNZXRob2RzRm9yTWV0aG9kVHlwZS5maWx0ZXIoeyAhJDAubWV0aG9kLnRocm93cyAmJiAhJDAubWV0aG9kLnJldGhyb3dzICYmICEkMC5tZXRob2QucmV0dXJuVHlwZU5hbWUuaXNWb2lkICYmICEkMC5tZXRob2QuaXNJbml0aWFsaXplciB9KSB7IC0lPgogICAgICAgIDwlPSBtZXRob2QuZ2l2ZW5Qcm9kdWNlQ29uc3RydWN0b3JOYW1lKHByZWZpeDogIlN0YXRpYyIpIC0lPiB7CiAgICAgICAgICAgIDwlPSBtZXRob2QuZ2l2ZW5Qcm9kdWNlQ29uc3RydWN0b3IocHJlZml4OiAiU3RhdGljIikgXyU+CiAgICAgICAgfQogICAgICAgIDwlXyB9IC0lPgogICAgICAgIDwlXyBmb3IgbWV0aG9kIGluIHdyYXBwZWRTdGF0aWNNZXRob2RzRm9yTWV0aG9kVHlwZS5maWx0ZXIoeyAoJDAubWV0aG9kLnRocm93cyB8fCAkMC5tZXRob2QucmV0aHJvd3MpICYmICEkMC5tZXRob2QuaXNJbml0aWFsaXplciB9KSB7IC0lPgogICAgICAgIDwlPSBtZXRob2QuZ2l2ZW5Db25zdHJ1Y3Rvck5hbWVUaHJvd3MocHJlZml4OiAiU3RhdGljIikgLSU+IHsKICAgICAgICAgICAgPCU9IG1ldGhvZC5naXZlbkNvbnN0cnVjdG9yVGhyb3dzKHByZWZpeDogIlN0YXRpYyIpIF8lPgogICAgICAgIH0KICAgICAgICA8JT0gbWV0aG9kLmdpdmVuUHJvZHVjZUNvbnN0cnVjdG9yTmFtZVRocm93cyhwcmVmaXg6ICJTdGF0aWMiKSAtJT4gewogICAgICAgICAgICA8JT0gbWV0aG9kLmdpdmVuUHJvZHVjZUNvbnN0cnVjdG9yVGhyb3dzKHByZWZpeDogIlN0YXRpYyIpIF8lPgogICAgICAgIH0KICAgICAgICA8JV8gfSAlPiA8JV8gLSU+CiAgICB9CgogICAgcHVibGljIHN0cnVjdCBTdGF0aWNWZXJpZnkgewogICAgICAgIGZpbGVwcml2YXRlIHZhciBtZXRob2Q6IFN0YXRpY01ldGhvZFR5cGUKCiAgICAgICAgPCVfIGZvciBtZXRob2QgaW4gd3JhcHBlZFN0YXRpY01ldGhvZHNGb3JNZXRob2RUeXBlIHsgLSU+CiAgICAgICAgPCU9IG1ldGhvZC52ZXJpZmljYXRpb25Qcm94eUNvbnN0cnVjdG9yTmFtZShwcmVmaXg6ICJTdGF0aWMiKSAtJT4geyA8JT0gbWV0aG9kLnZlcmlmaWNhdGlvblByb3h5Q29uc3RydWN0b3IocHJlZml4OiAiU3RhdGljIikgXyU+IH0KICAgICAgICA8JV8gfSAlPiA8JV8gLSU+CiAgICAgICAgPCVfIGZvciB2YXJpYWJsZSBpbiBhbGxTdGF0aWNWYXJpYWJsZXMgeyAtJT4KICAgICAgICA8JT0gcHJvcGVydHlUeXBlcyh2YXJpYWJsZSkgJT4KICAgICAgICA8JV8gfSAlPiA8JV8gLSU+CiAgICB9CgogICAgcHVibGljIHN0cnVjdCBTdGF0aWNQZXJmb3JtIHsKICAgICAgICBmaWxlcHJpdmF0ZSB2YXIgbWV0aG9kOiBTdGF0aWNNZXRob2RUeXBlCiAgICAgICAgdmFyIHBlcmZvcm1zOiBBbnkKCiAgICAgICAgPCVfIGZvciBtZXRob2QgaW4gd3JhcHBlZFN0YXRpY01ldGhvZHNGb3JNZXRob2RUeXBlIHsgLSU+CiAgICAgICAgPCU9IG1ldGhvZC5wZXJmb3JtUHJveHlDb25zdHJ1Y3Rvck5hbWUocHJlZml4OiAiU3RhdGljIikgLSU+IHsKICAgICAgICAgICAgPCU9IG1ldGhvZC5wZXJmb3JtUHJveHlDb25zdHJ1Y3RvcihwcmVmaXg6ICJTdGF0aWMiKSBfJT4KICAgICAgICB9CiAgICAgICAgPCVfIH0gJT4gPCVfIC0lPgogICAgfQoKICAgIDwlIH0gLSU+CiAgPCUjID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IE1FVEhPRCBUWVBFIC0lPjwlXyAtJT4KICAgIDwlXyBpZiAhd3JhcHBlZE1ldGhvZHMuaXNFbXB0eSB8fCAhYWxsVmFyaWFibGVzLmlzRW1wdHkgfHwgIWFsbFN1YnNjcmlwdHMuaXNFbXB0eSB7IC0lPgoKICAgIGZpbGVwcml2YXRlIGVudW0gTWV0aG9kVHlwZSB7CiAgICA8JV8gZm9yIG1ldGhvZCBpbiB3cmFwcGVkTWV0aG9kc0Zvck1ldGhvZFR5cGUgeyAtJT4KICAgICAgICA8JT0gbWV0aG9kLm1ldGhvZFR5cGVEZWNsYXJhdGlvbldpdGhQYXJhbWV0ZXJzKCkgXyU+CiAgICA8JV8gIH0gLSU+IDwlXyBmb3IgdmFyaWFibGUgaW4gYWxsVmFyaWFibGVzIHsgLSU+CiAgICAgICAgPCU9IHByb3BlcnR5TWV0aG9kVHlwZXModmFyaWFibGUpICU+CiAgICA8JV8gfSAlPiA8JV8gJT4gPCVfIGZvciB3cmFwcGVkIGluIHdyYXBwZWRTdWJzY3JpcHRzIHsgLSU+CiAgICAgICAgPCU9IHdyYXBwZWQuc3Vic2NyaXB0Q2FzZXMoKSBfJT4KICAgIDwlXyB9ICU+IDwlXyAlPgogICAgPCVfIC0lPgogICAgICAgIHN0YXRpYyBmdW5jIGNvbXBhcmVQYXJhbWV0ZXJzKGxoczogTWV0aG9kVHlwZSwgcmhzOiBNZXRob2RUeXBlLCBtYXRjaGVyOiBNYXRjaGVyKSAtPiBNYXRjaGVyLkNvbXBhcmlzb25SZXN1bHQgewogICAgICAgICAgICBzd2l0Y2ggKGxocywgcmhzKSB7IDwlXyBmb3IgbWV0aG9kIGluIHdyYXBwZWRNZXRob2RzRm9yTWV0aG9kVHlwZSB7ICU+CiAgICAgICAgICAgIDwlPSBtZXRob2QuZXF1YWxDYXNlcygpICU+CiAgICAgICAgICAgIDwlXyB9ICU+IDwlXyBmb3IgdmFyaWFibGUgaW4gd3JhcHBlZFZhcmlhYmxlcyB7IC0lPgogICAgICAgICAgICA8JT0gdmFyaWFibGUuY29tcGFyZUNhc2VzKCkgJT4KICAgICAgICAgICAgPCVfIH0gJT4gPCVfIC0lPiA8JV8gZm9yIHdyYXBwZWQgaW4gd3JhcHBlZFN1YnNjcmlwdHMgeyAtJT4KICAgICAgICAgICAgPCU9IHdyYXBwZWQuZXF1YWxDYXNlcygpICU+CiAgICAgICAgICAgIDwlXyB9ICU+IDwlXyBpZiB3cmFwcGVkTWV0aG9kcy5jb3VudCArIHZhcmlhYmxlQ2FzZXNDb3VudCArIHN1YnNjcmlwdHNDYXNlc0NvdW50ID4gMSB7IC0lPgogICAgICAgICAgICBkZWZhdWx0OiByZXR1cm4gLm5vbmUKICAgICAgICAgICAgPCVfIH0gLSU+CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICA8JV8gJT4KICAgICAgICBmdW5jIGludFZhbHVlKCkgLT4gSW50IHsKICAgICAgICAgICAgc3dpdGNoIHNlbGYgeyA8JV8gZm9yIG1ldGhvZCBpbiB3cmFwcGVkTWV0aG9kc0Zvck1ldGhvZFR5cGUgeyAlPgogICAgICAgICAgICA8JT0gbWV0aG9kLmludFZhbHVlQ2FzZSAtJT48JSB9ICU+CiAgICAgICAgICAgIDwlXyBmb3IgdmFyaWFibGUgaW4gYWxsVmFyaWFibGVzIHsgLSU+CiAgICAgICAgICAgIDwlPSBwcm9wZXJ0eU1ldGhvZFR5cGVzSW50VmFsdWUodmFyaWFibGUpICU+CiAgICAgICAgICAgIDwlXyB9ICU+IDwlXyBmb3Igd3JhcHBlZCBpbiB3cmFwcGVkU3Vic2NyaXB0cyB7IC0lPgogICAgICAgICAgICA8JT0gd3JhcHBlZC5pbnRWYWx1ZUNhc2UoKSAlPgogICAgICAgICAgICA8JV8gfSAtJT4KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmdW5jIGFzc2VydGlvbk5hbWUoKSAtPiBTdHJpbmcgewogICAgICAgICAgICBzd2l0Y2ggc2VsZiB7IDwlXyBmb3IgbWV0aG9kIGluIHdyYXBwZWRNZXRob2RzRm9yTWV0aG9kVHlwZSB7ICU+CiAgICAgICAgICAgIDwlPSBtZXRob2QuYXNzZXJ0aW9uTmFtZSAtJT48JSB9ICU+CiAgICAgICAgICAgIDwlXyBmb3IgdmFyaWFibGUgaW4gd3JhcHBlZFZhcmlhYmxlcyB7IC0lPgogICAgICAgICAgICA8JT0gdmFyaWFibGUuYXNzZXJ0aW9uTmFtZSAlPgogICAgICAgICAgICA8JV8gfSAlPiA8JV8gZm9yIHdyYXBwZWQgaW4gd3JhcHBlZFN1YnNjcmlwdHMgeyAtJT4KICAgICAgICAgICAgPCU9IHdyYXBwZWQuYXNzZXJ0aW9uTmFtZSAlPgogICAgICAgICAgICA8JV8gfSAtJT4KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIDwlXyB9IGVsc2UgeyAlPgogICAgZmlsZXByaXZhdGUgc3RydWN0IE1ldGhvZFR5cGUgewogICAgICAgIHN0YXRpYyBmdW5jIGNvbXBhcmVQYXJhbWV0ZXJzKGxoczogTWV0aG9kVHlwZSwgcmhzOiBNZXRob2RUeXBlLCBtYXRjaGVyOiBNYXRjaGVyKSAtPiBNYXRjaGVyLkNvbXBhcmlzb25SZXN1bHQgeyByZXR1cm4gLm1hdGNoIH0KICAgICAgICBmdW5jIGludFZhbHVlKCkgLT4gSW50IHsgcmV0dXJuIDAgfQogICAgICAgIGZ1bmMgYXNzZXJ0aW9uTmFtZSgpIC0+IFN0cmluZyB7IHJldHVybiAiIiB9CiAgICB9CiAgICA8JV8gfSAtJT48JV8gLSU+CgogICAgb3BlbiBjbGFzcyBHaXZlbjogU3R1YmJlZE1ldGhvZCB7CiAgICAgICAgZmlsZXByaXZhdGUgdmFyIG1ldGhvZDogTWV0aG9kVHlwZQoKICAgICAgICBwcml2YXRlIGluaXQobWV0aG9kOiBNZXRob2RUeXBlLCBwcm9kdWN0czogW1N0dWJQcm9kdWN0XSkgewogICAgICAgICAgICBzZWxmLm1ldGhvZCA9IG1ldGhvZAogICAgICAgICAgICBzdXBlci5pbml0KHByb2R1Y3RzKQogICAgICAgIH0KCiAgICAgICAgPCVfIGZvciB2YXJpYWJsZSBpbiBhbGxWYXJpYWJsZXMgeyAtJT4KICAgICAgICA8JT0gd3JhcFByb3BlcnR5KHZhcmlhYmxlKS5naXZlbkNvbnN0cnVjdG9yTmFtZSgpIC0lPiB7CiAgICAgICAgICAgIDwlPSB3cmFwUHJvcGVydHkodmFyaWFibGUpLmdpdmVuQ29uc3RydWN0b3IoKSBfJT4KICAgICAgICB9CiAgICAgICAgPCVfIH0gJT4gPCVfICU+CiAgICAgICAgPCVfIGZvciBtZXRob2QgaW4gd3JhcHBlZE1ldGhvZHNGb3JNZXRob2RUeXBlLmZpbHRlcih7ICEkMC5tZXRob2QucmV0dXJuVHlwZU5hbWUuaXNWb2lkICYmICEkMC5tZXRob2QuaXNJbml0aWFsaXplciB9KSB7IC0lPgogICAgICAgIDwlPSBtZXRob2QuZ2l2ZW5Db25zdHJ1Y3Rvck5hbWUoKSAtJT4gewogICAgICAgICAgICA8JT0gbWV0aG9kLmdpdmVuQ29uc3RydWN0b3IoKSBfJT4KICAgICAgICB9CiAgICAgICAgPCVfIH0gLSU+CiAgICAgICAgPCVfIGZvciBtZXRob2QgaW4gd3JhcHBlZE1ldGhvZHNGb3JNZXRob2RUeXBlLmZpbHRlcih7ICEkMC5tZXRob2QudGhyb3dzICYmICEkMC5tZXRob2QucmV0aHJvd3MgJiYgISQwLm1ldGhvZC5yZXR1cm5UeXBlTmFtZS5pc1ZvaWQgJiYgISQwLm1ldGhvZC5pc0luaXRpYWxpemVyIH0pIHsgLSU+CiAgICAgICAgPCU9IG1ldGhvZC5naXZlblByb2R1Y2VDb25zdHJ1Y3Rvck5hbWUoKSAtJT4gewogICAgICAgICAgICA8JT0gbWV0aG9kLmdpdmVuUHJvZHVjZUNvbnN0cnVjdG9yKCkgXyU+CiAgICAgICAgfQogICAgICAgIDwlXyB9IC0lPgogICAgICAgIDwlXyBmb3Igd3JhcHBlZCBpbiB3cmFwcGVkU3Vic2NyaXB0cyB7IC0lPgogICAgICAgIDwlPSB3cmFwcGVkLmdpdmVuQ29uc3RydWN0b3JOYW1lKCkgLSU+IHsKICAgICAgICAgICAgPCU9IHdyYXBwZWQuZ2l2ZW5Db25zdHJ1Y3RvcigpIF8lPgogICAgICAgIH0KICAgICAgICA8JV8gfSAtJT4KICAgICAgICA8JV8gZm9yIG1ldGhvZCBpbiB3cmFwcGVkTWV0aG9kc0Zvck1ldGhvZFR5cGUuZmlsdGVyKHsgKCQwLm1ldGhvZC50aHJvd3MgfHwgJDAubWV0aG9kLnJldGhyb3dzKSAmJiAhJDAubWV0aG9kLmlzSW5pdGlhbGl6ZXIgfSkgeyAtJT4KICAgICAgICA8JT0gbWV0aG9kLmdpdmVuQ29uc3RydWN0b3JOYW1lVGhyb3dzKCkgLSU+IHsKICAgICAgICAgICAgPCU9IG1ldGhvZC5naXZlbkNvbnN0cnVjdG9yVGhyb3dzKCkgXyU+CiAgICAgICAgfQogICAgICAgIDwlPSBtZXRob2QuZ2l2ZW5Qcm9kdWNlQ29uc3RydWN0b3JOYW1lVGhyb3dzKCkgLSU+IHsKICAgICAgICAgICAgPCU9IG1ldGhvZC5naXZlblByb2R1Y2VDb25zdHJ1Y3RvclRocm93cygpIF8lPgogICAgICAgIH0KICAgICAgICA8JV8gfSAlPiA8JV8gLSU+CiAgICB9CgogICAgcHVibGljIHN0cnVjdCBWZXJpZnkgewogICAgICAgIGZpbGVwcml2YXRlIHZhciBtZXRob2Q6IE1ldGhvZFR5cGUKCiAgICAgICAgPCVfIGZvciBtZXRob2QgaW4gd3JhcHBlZE1ldGhvZHNGb3JNZXRob2RUeXBlIHsgLSU+CiAgICAgICAgPCU9IG1ldGhvZC52ZXJpZmljYXRpb25Qcm94eUNvbnN0cnVjdG9yTmFtZSgpIC0lPiB7IDwlPSBtZXRob2QudmVyaWZpY2F0aW9uUHJveHlDb25zdHJ1Y3RvcigpIF8lPiB9CiAgICAgICAgPCVfIH0gJT4gPCVfIC0lPgogICAgICAgIDwlXyBmb3IgdmFyaWFibGUgaW4gYWxsVmFyaWFibGVzIHsgLSU+CiAgICAgICAgPCU9IHByb3BlcnR5VHlwZXModmFyaWFibGUpICU+CiAgICAgICAgPCVfIH0gJT4gPCVfIC0lPgogICAgICAgIDwlXyBmb3Igd3JhcHBlZCBpbiB3cmFwcGVkU3Vic2NyaXB0cyB7IC0lPgogICAgICAgIDwlPSB3cmFwcGVkLnZlcmlmeUNvbnN0cnVjdG9yTmFtZSgpIC0lPiB7IDwlPSB3cmFwcGVkLnZlcmlmeUNvbnN0cnVjdG9yKCkgXyU+IH0KICAgICAgICA8JV8gaWYgIXdyYXBwZWQucmVhZG9ubHkgeyAtJT4KICAgICAgICA8JT0gd3JhcHBlZC52ZXJpZnlDb25zdHJ1Y3Rvck5hbWUoc2V0OiB0cnVlKSAtJT4geyA8JT0gd3JhcHBlZC52ZXJpZnlDb25zdHJ1Y3RvcihzZXQ6IHRydWUpIF8lPiB9CiAgICAgICAgPCVfIH0gLSU+CiAgICAgICAgPCVfIH0gJT4gPCVfIC0lPgogICAgfQoKICAgIHB1YmxpYyBzdHJ1Y3QgUGVyZm9ybSB7CiAgICAgICAgZmlsZXByaXZhdGUgdmFyIG1ldGhvZDogTWV0aG9kVHlwZQogICAgICAgIHZhciBwZXJmb3JtczogQW55CgogICAgICAgIDwlXyBmb3IgbWV0aG9kIGluIHdyYXBwZWRNZXRob2RzRm9yTWV0aG9kVHlwZSB7IC0lPgogICAgICAgIDwlPSBtZXRob2QucGVyZm9ybVByb3h5Q29uc3RydWN0b3JOYW1lKCkgLSU+IHsKICAgICAgICAgICAgPCU9IG1ldGhvZC5wZXJmb3JtUHJveHlDb25zdHJ1Y3RvcigpIF8lPgogICAgICAgIH0KICAgICAgICA8JV8gfSAlPiA8JV8gLSU+CiAgICB9CgogIDwlIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBNT0NLIE1FVEhPRFMgLSU+PCVfIC0lPgogICAgcHVibGljIGZ1bmMgZ2l2ZW4oXyBtZXRob2Q6IEdpdmVuKSB7CiAgICAgICAgbWV0aG9kUmV0dXJuVmFsdWVzLmFwcGVuZChtZXRob2QpCiAgICB9CgogICAgcHVibGljIGZ1bmMgcGVyZm9ybShfIG1ldGhvZDogUGVyZm9ybSkgewogICAgICAgIG1ldGhvZFBlcmZvcm1WYWx1ZXMuYXBwZW5kKG1ldGhvZCkKICAgICAgICBtZXRob2RQZXJmb3JtVmFsdWVzLnNvcnQgeyAkMC5tZXRob2QuaW50VmFsdWUoKSA8ICQxLm1ldGhvZC5pbnRWYWx1ZSgpIH0KICAgIH0KCiAgICBwdWJsaWMgZnVuYyB2ZXJpZnkoXyBtZXRob2Q6IFZlcmlmeSwgY291bnQ6IENvdW50ID0gQ291bnQubW9yZU9yRXF1YWwodG86IDEpLCBmaWxlOiBTdGF0aWNTdHJpbmcgPSAjZmlsZSwgbGluZTogVUludCA9ICNsaW5lKSB7CiAgICAgICAgbGV0IGZ1bGxNYXRjaGVzID0gbWF0Y2hpbmdDYWxscyhtZXRob2QsIGZpbGU6IGZpbGUsIGxpbmU6IGxpbmUpCiAgICAgICAgbGV0IHN1Y2Nlc3MgPSBjb3VudC5tYXRjaGVzKGZ1bGxNYXRjaGVzKQogICAgICAgIGxldCBhc3NlcnRpb25OYW1lID0gbWV0aG9kLm1ldGhvZC5hc3NlcnRpb25OYW1lKCkKICAgICAgICBsZXQgZmVlZGJhY2s6IFN0cmluZyA9IHsKICAgICAgICAgICAgZ3VhcmQgIXN1Y2Nlc3MgZWxzZSB7IHJldHVybiAiIiB9CiAgICAgICAgICAgIHJldHVybiBVdGlscy5jbG9zZXN0Q2FsbHNNZXNzYWdlKAogICAgICAgICAgICAgICAgZm9yOiBzZWxmLmludm9jYXRpb25zLm1hcCB7IGludm9jYXRpb24gaW4KICAgICAgICAgICAgICAgICAgICBtYXRjaGVyLnNldChmaWxlOiBmaWxlLCBsaW5lOiBsaW5lKQogICAgICAgICAgICAgICAgICAgIGRlZmVyIHsgbWF0Y2hlci5jbGVhckZpbGVBbmRMaW5lKCkgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiBNZXRob2RUeXBlLmNvbXBhcmVQYXJhbWV0ZXJzKGxoczogaW52b2NhdGlvbiwgcmhzOiBtZXRob2QubWV0aG9kLCBtYXRjaGVyOiBtYXRjaGVyKQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIG5hbWU6IGFzc2VydGlvbk5hbWUKICAgICAgICAgICAgKQogICAgICAgIH0oKQogICAgICAgIE1vY2t5QXNzZXJ0KHN1Y2Nlc3MsICJFeHBlY3RlZDogXChjb3VudCkgaW52b2NhdGlvbnMgb2YgYFwoYXNzZXJ0aW9uTmFtZSlgLCBidXQgd2FzOiBcKGZ1bGxNYXRjaGVzKS5cKGZlZWRiYWNrKSIsIGZpbGU6IGZpbGUsIGxpbmU6IGxpbmUpCiAgICB9CgogICAgcHJpdmF0ZSBmdW5jIGFkZEludm9jYXRpb24oXyBjYWxsOiBNZXRob2RUeXBlKSB7CiAgICAgICAgc2VsZi5xdWV1ZS5zeW5jIHsgaW52b2NhdGlvbnMuYXBwZW5kKGNhbGwpIH0KICAgIH0KICAgIHByaXZhdGUgZnVuYyBtZXRob2RSZXR1cm5WYWx1ZShfIG1ldGhvZDogTWV0aG9kVHlwZSkgdGhyb3dzIC0+IFN0dWJQcm9kdWN0IHsKICAgICAgICBtYXRjaGVyLnNldChmaWxlOiBzZWxmLmZpbGUsIGxpbmU6IHNlbGYubGluZSkKICAgICAgICBkZWZlciB7IG1hdGNoZXIuY2xlYXJGaWxlQW5kTGluZSgpIH0KICAgICAgICBsZXQgY2FuZGlkYXRlcyA9IHNlcXVlbmNpbmdQb2xpY3kuc29ydGVkKG1ldGhvZFJldHVyblZhbHVlcywgYnk6IHsgJDAubWV0aG9kLmludFZhbHVlKCkgPiAkMS5tZXRob2QuaW50VmFsdWUoKSB9KQogICAgICAgIGxldCBtYXRjaGVkID0gY2FuZGlkYXRlcy5maXJzdCh3aGVyZTogeyAkMC5pc1ZhbGlkICYmIE1ldGhvZFR5cGUuY29tcGFyZVBhcmFtZXRlcnMobGhzOiAkMC5tZXRob2QsIHJoczogbWV0aG9kLCBtYXRjaGVyOiBtYXRjaGVyKS5pc0Z1bGxNYXRjaCB9KQogICAgICAgIGd1YXJkIGxldCBwcm9kdWN0ID0gbWF0Y2hlZD8uZ2V0UHJvZHVjdChwb2xpY3k6IHNlbGYuc3R1YmJpbmdQb2xpY3kpIGVsc2UgeyB0aHJvdyBNb2NrRXJyb3Iubm90U3R1YmVkIH0KICAgICAgICByZXR1cm4gcHJvZHVjdAogICAgfQogICAgcHJpdmF0ZSBmdW5jIG1ldGhvZFBlcmZvcm1WYWx1ZShfIG1ldGhvZDogTWV0aG9kVHlwZSkgLT4gQW55PyB7CiAgICAgICAgbWF0Y2hlci5zZXQoZmlsZTogc2VsZi5maWxlLCBsaW5lOiBzZWxmLmxpbmUpCiAgICAgICAgZGVmZXIgeyBtYXRjaGVyLmNsZWFyRmlsZUFuZExpbmUoKSB9CiAgICAgICAgbGV0IG1hdGNoZWQgPSBtZXRob2RQZXJmb3JtVmFsdWVzLnJldmVyc2VkKCkuZmlyc3QgeyBNZXRob2RUeXBlLmNvbXBhcmVQYXJhbWV0ZXJzKGxoczogJDAubWV0aG9kLCByaHM6IG1ldGhvZCwgbWF0Y2hlcjogbWF0Y2hlcikuaXNGdWxsTWF0Y2ggfQogICAgICAgIHJldHVybiBtYXRjaGVkPy5wZXJmb3JtcwogICAgfQogICAgcHJpdmF0ZSBmdW5jIG1hdGNoaW5nQ2FsbHMoXyBtZXRob2Q6IE1ldGhvZFR5cGUsIGZpbGU6IFN0YXRpY1N0cmluZz8sIGxpbmU6IFVJbnQ/KSAtPiBbTWV0aG9kVHlwZV0gewogICAgICAgIG1hdGNoZXIuc2V0KGZpbGU6IGZpbGUgPz8gc2VsZi5maWxlLCBsaW5lOiBsaW5lID8/IHNlbGYubGluZSkKICAgICAgICBkZWZlciB7IG1hdGNoZXIuY2xlYXJGaWxlQW5kTGluZSgpIH0KICAgICAgICByZXR1cm4gaW52b2NhdGlvbnMuZmlsdGVyIHsgTWV0aG9kVHlwZS5jb21wYXJlUGFyYW1ldGVycyhsaHM6ICQwLCByaHM6IG1ldGhvZCwgbWF0Y2hlcjogbWF0Y2hlcikuaXNGdWxsTWF0Y2ggfQogICAgfQogICAgcHJpdmF0ZSBmdW5jIG1hdGNoaW5nQ2FsbHMoXyBtZXRob2Q6IFZlcmlmeSwgZmlsZTogU3RhdGljU3RyaW5nPywgbGluZTogVUludD8pIC0+IEludCB7CiAgICAgICAgcmV0dXJuIG1hdGNoaW5nQ2FsbHMobWV0aG9kLm1ldGhvZCwgZmlsZTogZmlsZSwgbGluZTogbGluZSkuY291bnQKICAgIH0KICAgIHByaXZhdGUgZnVuYyBnaXZlbkdldHRlclZhbHVlPFQ+KF8gbWV0aG9kOiBNZXRob2RUeXBlLCBfIG1lc3NhZ2U6IFN0cmluZykgLT4gVCB7CiAgICAgICAgZG8gewogICAgICAgICAgICByZXR1cm4gdHJ5IG1ldGhvZFJldHVyblZhbHVlKG1ldGhvZCkuY2FzdGVkKCkKICAgICAgICB9IGNhdGNoIHsKICAgICAgICAgICAgb25GYXRhbEZhaWx1cmUobWVzc2FnZSkKICAgICAgICAgICAgRmFpbHVyZShtZXNzYWdlKQogICAgICAgIH0KICAgIH0KICAgIHByaXZhdGUgZnVuYyBvcHRpb25hbEdpdmVuR2V0dGVyVmFsdWU8VD4oXyBtZXRob2Q6IE1ldGhvZFR5cGUsIF8gbWVzc2FnZTogU3RyaW5nKSAtPiBUPyB7CiAgICAgICAgZG8gewogICAgICAgICAgICByZXR1cm4gdHJ5IG1ldGhvZFJldHVyblZhbHVlKG1ldGhvZCkuY2FzdGVkKCkKICAgICAgICB9IGNhdGNoIHsKICAgICAgICAgICAgcmV0dXJuIG5pbAogICAgICAgIH0KICAgIH0KICAgIHByaXZhdGUgZnVuYyBvbkZhdGFsRmFpbHVyZShfIG1lc3NhZ2U6IFN0cmluZykgewogICAgICAgIGd1YXJkIGxldCBmaWxlID0gc2VsZi5maWxlLCBsZXQgbGluZSA9IHNlbGYubGluZSBlbHNlIHsgcmV0dXJuIH0gLy8gTGV0IGlmIGZhaWwgaWYgY2Fubm90IGhhbmRsZSBncmF0ZWZ1bGx5CiAgICAgICAgU3dpZnR5TW9ja3lUZXN0T2JzZXJ2ZXIuaGFuZGxlRmF0YWxFcnJvcihtZXNzYWdlOiBtZXNzYWdlLCBmaWxlOiBmaWxlLCBsaW5lOiBsaW5lKQogICAgfQogIDwlIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBTVEFUSUMgTU9DSyBNRVRIT0RTIC0lPjwlXyAtJT4KICAgIDwlXyBpZiBjb25mb3Jtc1RvU3RhdGljTW9jayB7IC0lPgoKICAgIHN0YXRpYyBwdWJsaWMgZnVuYyBnaXZlbihfIG1ldGhvZDogU3RhdGljR2l2ZW4pIHsKICAgICAgICBtZXRob2RSZXR1cm5WYWx1ZXMuYXBwZW5kKG1ldGhvZCkKICAgIH0KCiAgICBzdGF0aWMgcHVibGljIGZ1bmMgcGVyZm9ybShfIG1ldGhvZDogU3RhdGljUGVyZm9ybSkgewogICAgICAgIG1ldGhvZFBlcmZvcm1WYWx1ZXMuYXBwZW5kKG1ldGhvZCkKICAgICAgICBtZXRob2RQZXJmb3JtVmFsdWVzLnNvcnQgeyAkMC5tZXRob2QuaW50VmFsdWUoKSA8ICQxLm1ldGhvZC5pbnRWYWx1ZSgpIH0KICAgIH0KCiAgICBzdGF0aWMgcHVibGljIGZ1bmMgdmVyaWZ5KF8gbWV0aG9kOiBTdGF0aWNWZXJpZnksIGNvdW50OiBDb3VudCA9IENvdW50Lm1vcmVPckVxdWFsKHRvOiAxKSwgZmlsZTogU3RhdGljU3RyaW5nID0gI2ZpbGUsIGxpbmU6IFVJbnQgPSAjbGluZSkgewogICAgICAgIGxldCBmdWxsTWF0Y2hlcyA9IG1hdGNoaW5nQ2FsbHMobWV0aG9kLCBmaWxlOiBmaWxlLCBsaW5lOiBsaW5lKQogICAgICAgIGxldCBzdWNjZXNzID0gY291bnQubWF0Y2hlcyhmdWxsTWF0Y2hlcykKICAgICAgICBsZXQgYXNzZXJ0aW9uTmFtZSA9IG1ldGhvZC5tZXRob2QuYXNzZXJ0aW9uTmFtZSgpCiAgICAgICAgbGV0IGZlZWRiYWNrOiBTdHJpbmcgPSB7CiAgICAgICAgICAgIGd1YXJkICFzdWNjZXNzIGVsc2UgeyByZXR1cm4gIiIgfQogICAgICAgICAgICByZXR1cm4gVXRpbHMuY2xvc2VzdENhbGxzTWVzc2FnZSgKICAgICAgICAgICAgICAgIGZvcjogc2VsZi5pbnZvY2F0aW9ucy5tYXAgeyBpbnZvY2F0aW9uIGluCiAgICAgICAgICAgICAgICAgICAgbWF0Y2hlci5zZXQoZmlsZTogZmlsZSwgbGluZTogbGluZSkKICAgICAgICAgICAgICAgICAgICBkZWZlciB7IG1hdGNoZXIuY2xlYXJGaWxlQW5kTGluZSgpIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gU3RhdGljTWV0aG9kVHlwZS5jb21wYXJlUGFyYW1ldGVycyhsaHM6IGludm9jYXRpb24sIHJoczogbWV0aG9kLm1ldGhvZCwgbWF0Y2hlcjogbWF0Y2hlcikKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBuYW1lOiBhc3NlcnRpb25OYW1lCiAgICAgICAgICAgICkKICAgICAgICB9KCkKICAgICAgICBNb2NreUFzc2VydChzdWNjZXNzLCAiRXhwZWN0ZWQ6IFwoY291bnQpIGludm9jYXRpb25zIG9mIGBcKGFzc2VydGlvbk5hbWUpYCwgYnV0IHdhczogXChmdWxsTWF0Y2hlcykuXChmZWVkYmFjaykiLCBmaWxlOiBmaWxlLCBsaW5lOiBsaW5lKQogICAgfQoKICAgIHN0YXRpYyBwcml2YXRlIGZ1bmMgYWRkSW52b2NhdGlvbihfIGNhbGw6IFN0YXRpY01ldGhvZFR5cGUpIHsKICAgICAgICBzZWxmLnF1ZXVlLnN5bmMgeyBpbnZvY2F0aW9ucy5hcHBlbmQoY2FsbCkgfQogICAgfQogICAgc3RhdGljIHByaXZhdGUgZnVuYyBtZXRob2RSZXR1cm5WYWx1ZShfIG1ldGhvZDogU3RhdGljTWV0aG9kVHlwZSkgdGhyb3dzIC0+IFN0dWJQcm9kdWN0IHsKICAgICAgICBsZXQgY2FuZGlkYXRlcyA9IHNlcXVlbmNpbmdQb2xpY3kuc29ydGVkKG1ldGhvZFJldHVyblZhbHVlcywgYnk6IHsgJDAubWV0aG9kLmludFZhbHVlKCkgPiAkMS5tZXRob2QuaW50VmFsdWUoKSB9KQogICAgICAgIGxldCBtYXRjaGVkID0gY2FuZGlkYXRlcy5maXJzdCh3aGVyZTogeyAkMC5pc1ZhbGlkICYmIFN0YXRpY01ldGhvZFR5cGUuY29tcGFyZVBhcmFtZXRlcnMobGhzOiAkMC5tZXRob2QsIHJoczogbWV0aG9kLCBtYXRjaGVyOiBtYXRjaGVyKS5pc0Z1bGxNYXRjaCB9KQogICAgICAgIGd1YXJkIGxldCBwcm9kdWN0ID0gbWF0Y2hlZD8uZ2V0UHJvZHVjdChwb2xpY3k6IHNlbGYuc3R1YmJpbmdQb2xpY3kpIGVsc2UgeyB0aHJvdyBNb2NrRXJyb3Iubm90U3R1YmVkIH0KICAgICAgICByZXR1cm4gcHJvZHVjdAogICAgfQogICAgc3RhdGljIHByaXZhdGUgZnVuYyBtZXRob2RQZXJmb3JtVmFsdWUoXyBtZXRob2Q6IFN0YXRpY01ldGhvZFR5cGUpIC0+IEFueT8gewogICAgICAgIGxldCBtYXRjaGVkID0gbWV0aG9kUGVyZm9ybVZhbHVlcy5yZXZlcnNlZCgpLmZpcnN0IHsgU3RhdGljTWV0aG9kVHlwZS5jb21wYXJlUGFyYW1ldGVycyhsaHM6ICQwLm1ldGhvZCwgcmhzOiBtZXRob2QsIG1hdGNoZXI6IG1hdGNoZXIpLmlzRnVsbE1hdGNoIH0KICAgICAgICByZXR1cm4gbWF0Y2hlZD8ucGVyZm9ybXMKICAgIH0KICAgIHN0YXRpYyBwcml2YXRlIGZ1bmMgbWF0Y2hpbmdDYWxscyhfIG1ldGhvZDogU3RhdGljTWV0aG9kVHlwZSwgZmlsZTogU3RhdGljU3RyaW5nPywgbGluZTogVUludD8pIC0+IFtTdGF0aWNNZXRob2RUeXBlXSB7CiAgICAgICAgbWF0Y2hlci5zZXQoZmlsZTogZmlsZSwgbGluZTogbGluZSkKICAgICAgICBkZWZlciB7IG1hdGNoZXIuY2xlYXJGaWxlQW5kTGluZSgpIH0KICAgICAgICByZXR1cm4gaW52b2NhdGlvbnMuZmlsdGVyIHsgU3RhdGljTWV0aG9kVHlwZS5jb21wYXJlUGFyYW1ldGVycyhsaHM6ICQwLCByaHM6IG1ldGhvZCwgbWF0Y2hlcjogbWF0Y2hlcikuaXNGdWxsTWF0Y2ggfQogICAgfQogICAgc3RhdGljIHByaXZhdGUgZnVuYyBtYXRjaGluZ0NhbGxzKF8gbWV0aG9kOiBTdGF0aWNWZXJpZnksIGZpbGU6IFN0YXRpY1N0cmluZz8sIGxpbmU6IFVJbnQ/KSAtPiBJbnQgewogICAgICAgIHJldHVybiBtYXRjaGluZ0NhbGxzKG1ldGhvZC5tZXRob2QsIGZpbGU6IGZpbGUsIGxpbmU6IGxpbmUpLmNvdW50CiAgICB9CiAgICBzdGF0aWMgcHJpdmF0ZSBmdW5jIGdpdmVuR2V0dGVyVmFsdWU8VD4oXyBtZXRob2Q6IFN0YXRpY01ldGhvZFR5cGUsIF8gbWVzc2FnZTogU3RyaW5nKSAtPiBUIHsKICAgICAgICBkbyB7CiAgICAgICAgICAgIHJldHVybiB0cnkgbWV0aG9kUmV0dXJuVmFsdWUobWV0aG9kKS5jYXN0ZWQoKQogICAgICAgIH0gY2F0Y2ggewogICAgICAgICAgICBGYWlsdXJlKG1lc3NhZ2UpCiAgICAgICAgfQogICAgfQogICAgc3RhdGljIHByaXZhdGUgZnVuYyBvcHRpb25hbEdpdmVuR2V0dGVyVmFsdWU8VD4oXyBtZXRob2Q6IFN0YXRpY01ldGhvZFR5cGUsIF8gbWVzc2FnZTogU3RyaW5nKSAtPiBUPyB7CiAgICAgICAgZG8gewogICAgICAgICAgICByZXR1cm4gdHJ5IG1ldGhvZFJldHVyblZhbHVlKG1ldGhvZCkuY2FzdGVkKCkKICAgICAgICB9IGNhdGNoIHsKICAgICAgICAgICAgcmV0dXJuIG5pbAogICAgICAgIH0KICAgIH0KICAgIDwlXyB9IC0lPgo8JV8gaWYgYXV0b01vY2thYmxlIHsgLSU+Cn0KCjwlXyB9IGVsc2UgeyAtJT4KLy8gc291cmNlcnk6ZW5kCjwlXyB9IC0lPgo8JSB9IC0lPgo8JV8gaWYgbW9ja2VkQ291bnQgPT0gMCB7IC0lPgovLyBTd2lmdHlNb2NreTogbm8gQXV0b01vY2thYmxlIGZvdW5kLgovLyBQbGVhc2UgZGVmaW5lIGFuZCBpbmhlcml0IGZyb20gQXV0b01vY2thYmxlLCBvciBhbm5vdGF0ZSBwcm90b2NvbHMgdG8gYmUgbW9ja2VkCjwlXyB9IC0lPgo="
    )
    static let prototype = File(
        name: "Mock.swifttemplate",
        contents: "PCVfCmxldCBtb2NrVHlwZU5hbWUgPSAiUHJvdG90eXBlIgpmdW5jIHN3aWZ0TGludFJ1bGVzKF8gYXJndW1lbnRzOiBbU3RyaW5nOiBBbnldKSAtPiBbU3RyaW5nXSB7CiAgICByZXR1cm4gc3RyaW5nQXJyYXkoZnJvbUFyZ3VtZW50czogYXJndW1lbnRzLCBmb3JLZXk6ICJleGNsdWRlZFN3aWZ0TGludFJ1bGVzIikubWFwIHsgcnVsZSBpbgogICAgICAgIHJldHVybiAiLy9zd2lmdGxpbnQ6ZGlzYWJsZSBcKHJ1bGUpIgogICAgfQp9CgpmdW5jIHByb2plY3RJbXBvcnRzKF8gYXJndW1lbnRzOiBbU3RyaW5nOiBBbnldKSAtPiBbU3RyaW5nXSB7CiAgICByZXR1cm4gaW1wb3J0cyhhcmd1bWVudHMpICsgdGVzdGFibGVJbXBvcnRzKGFyZ3VtZW50cykKfQoKZnVuYyBpbXBvcnRzKF8gYXJndW1lbnRzOiBbU3RyaW5nOiBBbnldKSAtPiBbU3RyaW5nXSB7CiAgICByZXR1cm4gc3RyaW5nQXJyYXkoZnJvbUFyZ3VtZW50czogYXJndW1lbnRzLCBmb3JLZXk6ICJpbXBvcnQiKQogICAgICAgIC5tYXAgeyByZXR1cm4gImltcG9ydCBcKCQwKSIgfQp9CgpmdW5jIHRlc3RhYmxlSW1wb3J0cyhfIGFyZ3VtZW50czogW1N0cmluZzogQW55XSkgLT4gW1N0cmluZ10gewogICAgcmV0dXJuIHN0cmluZ0FycmF5KGZyb21Bcmd1bWVudHM6IGFyZ3VtZW50cywgZm9yS2V5OiAidGVzdGFibGUiKQogICAgICAgIC5tYXAgeyByZXR1cm4gIkB0ZXN0YWJsZSBpbXBvcnQgXCgkMCkiIH0KfQoKLy8vIFtJbnRlcm5hbF0gR2V0IHZhbHVlIGZyb20gZGljdGlvbmFyeQovLy8gLSBQYXJhbWV0ZXJzOgovLy8gICAtIGZyb21Bcmd1bWVudHM6IGRpY3Rpb25hcnkKLy8vICAgLSBmb3JLZXk6IGRpY3Rpb25hcnkga2V5Ci8vLyAtIFJldHVybnM6IGFycmF5IG9mIHN0cmluZ3MsIGlmIGtleSBub3QgZm91bmQsIHJldHVybnMgZW1wdHkgYXJyYXkuCi8vLyAtIE5vdGU6IElmIHNvdXJjZXJ5IGFyZ3VtZW50cyBjb250YWludHMgb25seSBvbmUgZWxlbWVudCwgdGhlbiBzaW5nbGUgdmFsdWUgaXMgc3RvcmVkLCBvdGhlcndpc2UgYXJyYXkgb2YgZWxlbWVudHMuIFRoaXMgbWV0aG9kIGFsd2F5cyBnZXRzIGFycmF5IG9mIGVsZW1lbnRzLgpmdW5jIHN0cmluZ0FycmF5KGZyb21Bcmd1bWVudHMgYXJndW1lbnRzOiBbU3RyaW5nOiBBbnldLCBmb3JLZXkga2V5OiBTdHJpbmcpIC0+IFtTdHJpbmddIHsKCiAgICBpZiBsZXQgYXJndW1lbnQgPSBhcmd1bWVudHNba2V5XSBhcz8gU3RyaW5nIHsKICAgICAgICByZXR1cm4gW2FyZ3VtZW50XQogICAgfSBlbHNlIGlmIGxldCBtYW55QXJndW1lbnRzID0gYXJndW1lbnRzW2tleV0gYXM/IFtTdHJpbmddIHsKICAgICAgICByZXR1cm4gbWFueUFyZ3VtZW50cwogICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gW10KICAgIH0KfQpfJT4KLy8gR2VuZXJhdGVkIHdpdGggU3dpZnR5UHJvdG90eXBlIDQuMi4wCi8vIFJlcXVpcmVkIFNvdXJjZXJ5OiAxLjguMAoKPCVfIGZvciBydWxlIGluIHN3aWZ0TGludFJ1bGVzKGFyZ3VtZW50KSB7IC0lPgogICAgPCVfICU+PCU9IHJ1bGUgJT4KPCVfIH0gLSU+CgppbXBvcnQgU3dpZnR5UHJvdG90eXBlCjwlIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBJTVBPUlRTIC0lPjwlXyAtJT4KICAgIDwlXyBmb3IgcHJvamVjdEltcG9ydCBpbiBwcm9qZWN0SW1wb3J0cyhhcmd1bWVudCkgeyAtJT4KICAgICAgICA8JV8gJT48JT0gcHJvamVjdEltcG9ydCAlPgogICAgPCVfIH0gLSU+CiAgICA8JSMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PSBJTVBPUlRTIEluQVBQIChhZ2dyZWdhdGVkIGFyZ3VtZW50KSAtJT48JV8gLSU+CiAgICA8JV8gaWYgbGV0IHN3aWZ0eU1vY2t5QXJncyA9IGFyZ3VtZW50WyJzd2lmdHlNb2NreSJdIGFzPyBbU3RyaW5nOiBBbnldIHsgLSU+CiAgICAgICAgPCVfIGZvciBwcm9qZWN0SW1wb3J0IGluIHByb2plY3RJbXBvcnRzKHN3aWZ0eU1vY2t5QXJncykgeyAtJT4KICAgICAgICAgICAgPCVfICU+PCU9IHByb2plY3RJbXBvcnQgJT4KICAgICAgICA8JV8gfSAtJT4KICAgIDwlXyB9IC0lPgo8JV8KY2xhc3MgQ3VycmVudCB7CiAgICBzdGF0aWMgdmFyIHNlbGZUeXBlOiBTdHJpbmcgPSAiU2VsZiIKICAgIHN0YXRpYyB2YXIgYWNjZXNzTW9kaWZpZXI6IFN0cmluZyA9ICJvcGVuIgp9Ci8vIENvbGxpc2lvbiBtYW5hZ2VtZW50CmZ1bmMgYXJlVGhlcmVDb2xsaXNpb25zKGJldHdlZW4gbWV0aG9kczogW01ldGhvZFdyYXBwZXJdKSAtPiBCb29sIHsKICAgIGxldCBnaXZlblNldCA9IFNldDxTdHJpbmc+KG1ldGhvZHMubWFwKHsgJDAuZ2l2ZW5Db25zdHJ1Y3Rvck5hbWUocHJlZml4OiAiIikgfSkpCiAgICBndWFyZCBnaXZlblNldC5jb3VudCA9PSBtZXRob2RzLmNvdW50IGVsc2UgeyByZXR1cm4gdHJ1ZSB9IC8vIHRoZXJlIHdvdWxkIGJlIGNvbmZsaWN0cyBpbiBHaXZlbgogICAgbGV0IHZlcmlmeVNldCA9IFNldDxTdHJpbmc+KG1ldGhvZHMubWFwKHsgJDAudmVyaWZpY2F0aW9uUHJveHlDb25zdHJ1Y3Rvck5hbWUocHJlZml4OiAiIikgfSkpCiAgICBndWFyZCB2ZXJpZnlTZXQuY291bnQgPT0gbWV0aG9kcy5jb3VudCBlbHNlIHsgcmV0dXJuIHRydWUgfSAvLyB0aGVyZSB3b3VsZCBiZSBjb25mbGljdHMgaW4gVmVyaWZ5CiAgICByZXR1cm4gZmFsc2UKfQoKLy8gaGVybHBlcnMKZnVuYyB1bmlxdWVzKG1ldGhvZHM6IFtTb3VyY2VyeVJ1bnRpbWUuTWV0aG9kXSkgLT4gW1NvdXJjZXJ5UnVudGltZS5NZXRob2RdIHsKICAgIGZ1bmMgcmV0dXJuVHlwZVN0cmlwcGVkKF8gbWV0aG9kOiBTb3VyY2VyeVJ1bnRpbWUuTWV0aG9kKSAtPiBTdHJpbmcgewogICAgICAgIGxldCByZXR1cm5UeXBlUmF3ID0gIlwobWV0aG9kLnJldHVyblR5cGVOYW1lKSIKICAgICAgICB2YXIgc3RyaXBwZWQ6IFN0cmluZyA9IHsKICAgICAgICAgICAgZ3VhcmQgbGV0IHJhbmdlID0gcmV0dXJuVHlwZVJhdy5yYW5nZShvZjogIndoZXJlIikgZWxzZSB7IHJldHVybiByZXR1cm5UeXBlUmF3IH0KICAgICAgICAgICAgdmFyIHN0cmlwcGVkID0gcmV0dXJuVHlwZVJhdwogICAgICAgICAgICBzdHJpcHBlZC5yZW1vdmVTdWJyYW5nZSgocmFuZ2UubG93ZXJCb3VuZCkuLi4pCiAgICAgICAgICAgIHJldHVybiBzdHJpcHBlZAogICAgICAgIH0oKQogICAgICAgIHN0cmlwcGVkID0gc3RyaXBwZWQudHJpbW1pbmdDaGFyYWN0ZXJzKGluOiBDaGFyYWN0ZXJTZXQoY2hhcmFjdGVyc0luOiAiICIpKQogICAgICAgIHJldHVybiBzdHJpcHBlZAogICAgfQoKICAgIGZ1bmMgYXJlU2FtZVBhcmFtcyhfIHAxOiBTb3VyY2VyeVJ1bnRpbWUuTWV0aG9kUGFyYW1ldGVyLCBfIHAyOiBTb3VyY2VyeVJ1bnRpbWUuTWV0aG9kUGFyYW1ldGVyKSAtPiBCb29sIHsKICAgICAgICBndWFyZCBwMS5hcmd1bWVudExhYmVsID09IHAyLmFyZ3VtZW50TGFiZWwgZWxzZSB7IHJldHVybiBmYWxzZSB9CiAgICAgICAgZ3VhcmQgcDEubmFtZSA9PSBwMi5uYW1lIGVsc2UgeyByZXR1cm4gZmFsc2UgfQogICAgICAgIGd1YXJkIHAxLmFyZ3VtZW50TGFiZWwgPT0gcDIuYXJndW1lbnRMYWJlbCBlbHNlIHsgcmV0dXJuIGZhbHNlIH0KICAgICAgICBndWFyZCBwMS50eXBlTmFtZS5uYW1lID09IHAyLnR5cGVOYW1lLm5hbWUgZWxzZSB7IHJldHVybiBmYWxzZSB9CiAgICAgICAgZ3VhcmQgcDEuYWN0dWFsVHlwZU5hbWU/Lm5hbWUgPT0gcDIuYWN0dWFsVHlwZU5hbWU/Lm5hbWUgZWxzZSB7IHJldHVybiBmYWxzZSB9CiAgICAgICAgcmV0dXJuIHRydWUKICAgIH0KCiAgICBmdW5jIGFyZVNhbWVNZXRob2RzKF8gbTE6IFNvdXJjZXJ5UnVudGltZS5NZXRob2QsIF8gbTI6IFNvdXJjZXJ5UnVudGltZS5NZXRob2QpIC0+IEJvb2wgewogICAgICAgIGd1YXJkIG0xLm5hbWUgIT0gbTIubmFtZSBlbHNlIHsgcmV0dXJuIG0xLnJldHVyblR5cGVOYW1lID09IG0yLnJldHVyblR5cGVOYW1lIH0KICAgICAgICBndWFyZCBtMS5zZWxlY3Rvck5hbWUgPT0gbTIuc2VsZWN0b3JOYW1lIGVsc2UgeyByZXR1cm4gZmFsc2UgfQogICAgICAgIGd1YXJkIG0xLnBhcmFtZXRlcnMuY291bnQgPT0gbTIucGFyYW1ldGVycy5jb3VudCBlbHNlIHsgcmV0dXJuIGZhbHNlIH0KCiAgICAgICAgbGV0IHAxID0gbTEucGFyYW1ldGVycwogICAgICAgIGxldCBwMiA9IG0yLnBhcmFtZXRlcnMKCiAgICAgICAgZm9yIGkgaW4gMC4uPHAxLmNvdW50IHsKICAgICAgICAgICAgaWYgIWFyZVNhbWVQYXJhbXMocDFbaV0scDJbaV0pIHsgcmV0dXJuIGZhbHNlIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBtMS5yZXR1cm5UeXBlTmFtZSA9PSBtMi5yZXR1cm5UeXBlTmFtZQogICAgfQoKICAgIHJldHVybiBtZXRob2RzLnJlZHVjZShbXSwgeyAocmVzdWx0LCBlbGVtZW50KSAtPiBbU291cmNlcnlSdW50aW1lLk1ldGhvZF0gaW4KICAgICAgICBndWFyZCAhcmVzdWx0LmNvbnRhaW5zKHdoZXJlOiB7IGFyZVNhbWVNZXRob2RzKCQwLGVsZW1lbnQpIH0pIGVsc2UgeyByZXR1cm4gcmVzdWx0IH0KICAgICAgICByZXR1cm4gcmVzdWx0ICsgW2VsZW1lbnRdCiAgICB9KQp9CgpmdW5jIHVuaXF1ZXNXaXRob3V0R2VuZXJpY0NvbnN0cmFpbnRzKG1ldGhvZHM6IFtTb3VyY2VyeVJ1bnRpbWUuTWV0aG9kXSkgLT4gW1NvdXJjZXJ5UnVudGltZS5NZXRob2RdIHsKICAgIGZ1bmMgcmV0dXJuVHlwZVN0cmlwcGVkKF8gbWV0aG9kOiBTb3VyY2VyeVJ1bnRpbWUuTWV0aG9kKSAtPiBTdHJpbmcgewogICAgICAgIGxldCByZXR1cm5UeXBlUmF3ID0gIlwobWV0aG9kLnJldHVyblR5cGVOYW1lKSIKICAgICAgICB2YXIgc3RyaXBwZWQ6IFN0cmluZyA9IHsKICAgICAgICAgICAgZ3VhcmQgbGV0IHJhbmdlID0gcmV0dXJuVHlwZVJhdy5yYW5nZShvZjogIndoZXJlIikgZWxzZSB7IHJldHVybiByZXR1cm5UeXBlUmF3IH0KICAgICAgICAgICAgdmFyIHN0cmlwcGVkID0gcmV0dXJuVHlwZVJhdwogICAgICAgICAgICBzdHJpcHBlZC5yZW1vdmVTdWJyYW5nZSgocmFuZ2UubG93ZXJCb3VuZCkuLi4pCiAgICAgICAgICAgIHJldHVybiBzdHJpcHBlZAogICAgICAgIH0oKQogICAgICAgIHN0cmlwcGVkID0gc3RyaXBwZWQudHJpbW1pbmdDaGFyYWN0ZXJzKGluOiBDaGFyYWN0ZXJTZXQoY2hhcmFjdGVyc0luOiAiICIpKQogICAgICAgIHJldHVybiBzdHJpcHBlZAogICAgfQoKICAgIGZ1bmMgYXJlU2FtZVBhcmFtcyhfIHAxOiBTb3VyY2VyeVJ1bnRpbWUuTWV0aG9kUGFyYW1ldGVyLCBfIHAyOiBTb3VyY2VyeVJ1bnRpbWUuTWV0aG9kUGFyYW1ldGVyKSAtPiBCb29sIHsKICAgICAgICBndWFyZCBwMS5hcmd1bWVudExhYmVsID09IHAyLmFyZ3VtZW50TGFiZWwgZWxzZSB7IHJldHVybiBmYWxzZSB9CiAgICAgICAgZ3VhcmQgcDEubmFtZSA9PSBwMi5uYW1lIGVsc2UgeyByZXR1cm4gZmFsc2UgfQogICAgICAgIGd1YXJkIHAxLmFyZ3VtZW50TGFiZWwgPT0gcDIuYXJndW1lbnRMYWJlbCBlbHNlIHsgcmV0dXJuIGZhbHNlIH0KICAgICAgICBndWFyZCBwMS50eXBlTmFtZS5uYW1lID09IHAyLnR5cGVOYW1lLm5hbWUgZWxzZSB7IHJldHVybiBmYWxzZSB9CiAgICAgICAgZ3VhcmQgcDEuYWN0dWFsVHlwZU5hbWU/Lm5hbWUgPT0gcDIuYWN0dWFsVHlwZU5hbWU/Lm5hbWUgZWxzZSB7IHJldHVybiBmYWxzZSB9CiAgICAgICAgcmV0dXJuIHRydWUKICAgIH0KCiAgICBmdW5jIGFyZVNhbWVNZXRob2RzKF8gbTE6IFNvdXJjZXJ5UnVudGltZS5NZXRob2QsIF8gbTI6IFNvdXJjZXJ5UnVudGltZS5NZXRob2QpIC0+IEJvb2wgewogICAgICAgIGd1YXJkIG0xLm5hbWUgIT0gbTIubmFtZSBlbHNlIHsgcmV0dXJuIHJldHVyblR5cGVTdHJpcHBlZChtMSkgPT0gcmV0dXJuVHlwZVN0cmlwcGVkKG0yKSB9CiAgICAgICAgZ3VhcmQgbTEuc2VsZWN0b3JOYW1lID09IG0yLnNlbGVjdG9yTmFtZSBlbHNlIHsgcmV0dXJuIGZhbHNlIH0KICAgICAgICBndWFyZCBtMS5wYXJhbWV0ZXJzLmNvdW50ID09IG0yLnBhcmFtZXRlcnMuY291bnQgZWxzZSB7IHJldHVybiBmYWxzZSB9CgogICAgICAgIGxldCBwMSA9IG0xLnBhcmFtZXRlcnMKICAgICAgICBsZXQgcDIgPSBtMi5wYXJhbWV0ZXJzCgogICAgICAgIGZvciBpIGluIDAuLjxwMS5jb3VudCB7CiAgICAgICAgICAgIGlmICFhcmVTYW1lUGFyYW1zKHAxW2ldLHAyW2ldKSB7IHJldHVybiBmYWxzZSB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gcmV0dXJuVHlwZVN0cmlwcGVkKG0xKSA9PSByZXR1cm5UeXBlU3RyaXBwZWQobTIpCiAgICB9CgogICAgcmV0dXJuIG1ldGhvZHMucmVkdWNlKFtdLCB7IChyZXN1bHQsIGVsZW1lbnQpIC0+IFtTb3VyY2VyeVJ1bnRpbWUuTWV0aG9kXSBpbgogICAgICAgIGd1YXJkICFyZXN1bHQuY29udGFpbnMod2hlcmU6IHsgYXJlU2FtZU1ldGhvZHMoJDAsZWxlbWVudCkgfSkgZWxzZSB7IHJldHVybiByZXN1bHQgfQogICAgICAgIHJldHVybiByZXN1bHQgKyBbZWxlbWVudF0KICAgIH0pCn0KCmZ1bmMgdW5pcXVlcyh2YXJpYWJsZXM6IFtTb3VyY2VyeVJ1bnRpbWUuVmFyaWFibGVdKSAtPiBbU291cmNlcnlSdW50aW1lLlZhcmlhYmxlXSB7CiAgICByZXR1cm4gdmFyaWFibGVzLnJlZHVjZShbXSwgeyAocmVzdWx0LCBlbGVtZW50KSAtPiBbU291cmNlcnlSdW50aW1lLlZhcmlhYmxlXSBpbgogICAgICAgIGd1YXJkICFyZXN1bHQuY29udGFpbnMod2hlcmU6IHsgJDAubmFtZSA9PSBlbGVtZW50Lm5hbWUgfSkgZWxzZSB7IHJldHVybiByZXN1bHQgfQogICAgICAgIHJldHVybiByZXN1bHQgKyBbZWxlbWVudF0KICAgIH0pCn0KCmZ1bmMgd3JhcE1ldGhvZChfIG1ldGhvZDogU291cmNlcnlSdW50aW1lLk1ldGhvZCkgLT4gTWV0aG9kV3JhcHBlciB7CiAgICByZXR1cm4gTWV0aG9kV3JhcHBlcihtZXRob2QpCn0KCmZ1bmMgd3JhcFN1YnNjcmlwdChfIHdyYXBwZWQ6IFNvdXJjZXJ5UnVudGltZS5TdWJzY3JpcHQpIC0+IFN1YnNjcmlwdFdyYXBwZXIgewogICAgcmV0dXJuIFN1YnNjcmlwdFdyYXBwZXIod3JhcHBlZCkKfQoKZnVuYyBqdXN0V3JhcChfIHZhcmlhYmxlOiBTb3VyY2VyeVJ1bnRpbWUuVmFyaWFibGUpIC0+IFZhcmlhYmxlV3JhcHBlciB7IHJldHVybiB3cmFwUHJvcGVydHkodmFyaWFibGUpIH0KZnVuYyB3cmFwUHJvcGVydHkoXyB2YXJpYWJsZTogU291cmNlcnlSdW50aW1lLlZhcmlhYmxlLCBfIHNjb3BlOiBTdHJpbmcgPSAiIikgLT4gVmFyaWFibGVXcmFwcGVyIHsKICAgIHJldHVybiBWYXJpYWJsZVdyYXBwZXIodmFyaWFibGUsIHNjb3BlOiBzY29wZSkKfQoKZnVuYyBzdHViUHJvcGVydHkoXyB2YXJpYWJsZTogU291cmNlcnlSdW50aW1lLlZhcmlhYmxlLCBfIHNjb3BlOiBTdHJpbmcpIC0+IFN0cmluZyB7CiAgICBsZXQgd3JhcHBlciA9IFZhcmlhYmxlV3JhcHBlcih2YXJpYWJsZSwgc2NvcGU6IHNjb3BlKQogICAgcmV0dXJuICJcKHdyYXBwZXIucHJvdG90eXBlKVxuXHRcKHdyYXBwZXIucHJpdmF0ZVByb3RvdHlwZSkiCn0KCmZ1bmMgcHJvcGVydHlUeXBlcyhfIHZhcmlhYmxlOiBTb3VyY2VyeVJ1bnRpbWUuVmFyaWFibGUpIC0+IFN0cmluZyB7CiAgICBsZXQgd3JhcHBlciA9IFZhcmlhYmxlV3JhcHBlcih2YXJpYWJsZSwgc2NvcGU6ICJzY29wZSIpCiAgICByZXR1cm4gIlwod3JhcHBlci5wcm9wZXJ0eUdldCgpKSIgKyAod3JhcHBlci5yZWFkb25seSA/ICIiIDogIlxuXHRcdFwod3JhcHBlci5wcm9wZXJ0eVNldCgpKSIpCn0KCmZ1bmMgcHJvcGVydHlNZXRob2RUeXBlcyhfIHZhcmlhYmxlOiBTb3VyY2VyeVJ1bnRpbWUuVmFyaWFibGUpIC0+IFN0cmluZyB7CiAgICBsZXQgd3JhcHBlciA9IFZhcmlhYmxlV3JhcHBlcih2YXJpYWJsZSwgc2NvcGU6ICIiKQogICAgcmV0dXJuICJcKHdyYXBwZXIucHJvcGVydHlDYXNlR2V0KCkpIiArICh3cmFwcGVyLnJlYWRvbmx5ID8gIiIgOiAiXG5cdFx0XCh3cmFwcGVyLnByb3BlcnR5Q2FzZVNldCgpKSIpCn0KCmZ1bmMgcHJvcGVydHlNZXRob2RUeXBlc0ludFZhbHVlKF8gdmFyaWFibGU6IFNvdXJjZXJ5UnVudGltZS5WYXJpYWJsZSkgLT4gU3RyaW5nIHsKICAgIGxldCB3cmFwcGVyID0gVmFyaWFibGVXcmFwcGVyKHZhcmlhYmxlLCBzY29wZTogIiIpCiAgICByZXR1cm4gIlwod3JhcHBlci5wcm9wZXJ0eUNhc2VHZXRJbnRWYWx1ZSgpKSIgKyAod3JhcHBlci5yZWFkb25seSA/ICIiIDogIlxuXHRcdFx0XCh3cmFwcGVyLnByb3BlcnR5Q2FzZVNldEludFZhbHVlKCkpIikKfQoKZnVuYyBwcm9wZXJ0eVJlZ2lzdGVyKF8gdmFyaWFibGU6IFNvdXJjZXJ5UnVudGltZS5WYXJpYWJsZSkgewogICAgbGV0IHdyYXBwZXIgPSBWYXJpYWJsZVdyYXBwZXIodmFyaWFibGUsIHNjb3BlOiAiIikKICAgIE1ldGhvZFdyYXBwZXIucmVnaXN0ZXIod3JhcHBlci5wcm9wZXJ0eUNhc2VHZXROYW1lLHdyYXBwZXIucHJvcGVydHlDYXNlR2V0TmFtZSx3cmFwcGVyLnByb3BlcnR5Q2FzZUdldE5hbWUpCiAgICBndWFyZCAhd3JhcHBlci5yZWFkb25seSBlbHNlIHsgcmV0dXJuIH0KICAgIE1ldGhvZFdyYXBwZXIucmVnaXN0ZXIod3JhcHBlci5wcm9wZXJ0eUNhc2VTZXROYW1lLHdyYXBwZXIucHJvcGVydHlDYXNlU2V0TmFtZSx3cmFwcGVyLnByb3BlcnR5Q2FzZUdldE5hbWUpCn0KY2xhc3MgSGVscGVycyB7CiAgICBzdGF0aWMgZnVuYyBzcGxpdChfIHN0cmluZzogU3RyaW5nLCBieUZpcnN0T2NjdXJlbmNlT2Ygd29yZDogU3RyaW5nKSAtPiAoU3RyaW5nLCBTdHJpbmcpIHsKICAgICAgICBndWFyZCBsZXQgd29yZFJhbmdlID0gc3RyaW5nLnJhbmdlKG9mOiB3b3JkKSBlbHNlIHsgcmV0dXJuIChzdHJpbmcsICIiKSB9CiAgICAgICAgbGV0IHNlbGZSYW5nZSA9IHN0cmluZy5yYW5nZShvZjogc3RyaW5nKSEKICAgICAgICBsZXQgYmVmb3JlID0gU3RyaW5nKHN0cmluZ1tzZWxmUmFuZ2UubG93ZXJCb3VuZC4uPHdvcmRSYW5nZS5sb3dlckJvdW5kXSkKICAgICAgICBsZXQgYWZ0ZXIgPSBTdHJpbmcoc3RyaW5nW3dvcmRSYW5nZS51cHBlckJvdW5kLi48c2VsZlJhbmdlLnVwcGVyQm91bmRdKQogICAgICAgIHJldHVybiAoYmVmb3JlLCBhZnRlcikKICAgIH0KICAgIHN0YXRpYyBmdW5jIGV4dHJhY3RBc3NvY2lhdGVkVHlwZXMoZnJvbSBhbm5vdGF0ZWQ6IFNvdXJjZXJ5UnVudGltZS5Bbm5vdGF0ZWQpIC0+IFtTdHJpbmddPyB7CiAgICAgICAgaWYgbGV0IHR5cGVzID0gYW5ub3RhdGVkLmFubm90YXRpb25zWyJhc3NvY2lhdGVkdHlwZSJdIGFzPyBbU3RyaW5nXSB7CiAgICAgICAgICAgIHJldHVybiB0eXBlcy5yZXZlcnNlZCgpCiAgICAgICAgfSBlbHNlIGlmIGxldCB0eXBlID0gYW5ub3RhdGVkLmFubm90YXRpb25zWyJhc3NvY2lhdGVkdHlwZSJdIGFzPyBTdHJpbmcgewogICAgICAgICAgICByZXR1cm4gW3R5cGVdCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIG5pbAogICAgICAgIH0KICAgIH0KICAgIHN0YXRpYyBmdW5jIGV4dHJhY3RXaGVyZUNsYXVzZShmcm9tIGFubm90YXRlZDogU291cmNlcnlSdW50aW1lLkFubm90YXRlZCkgLT4gU3RyaW5nPyB7CiAgICAgICAgaWYgbGV0IGNvbnN0cmFpbnRzID0gYW5ub3RhdGVkLmFubm90YXRpb25zWyJ3aGVyZSJdIGFzPyBbU3RyaW5nXSB7CiAgICAgICAgICAgIHJldHVybiAiIHdoZXJlIFwoY29uc3RyYWludHMucmV2ZXJzZWQoKS5qb2luZWQoc2VwYXJhdG9yOiAiLCAiKSkiCiAgICAgICAgfSBlbHNlIGlmIGxldCBjb25zdHJhaW50ID0gYW5ub3RhdGVkLmFubm90YXRpb25zWyJ3aGVyZSJdIGFzPyBTdHJpbmcgewogICAgICAgICAgICByZXR1cm4gIiB3aGVyZSBcKGNvbnN0cmFpbnQpIgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBuaWwKICAgICAgICB9CiAgICB9CiAgICAvLy8gRXh0cmFjdCBhbGwgdHlwZWFsaWFzZXMgZnJvbSAiYW5ub3RhdGlvbnMiCiAgICBzdGF0aWMgZnVuYyBleHRyYWN0VHlwZWFsaWFzZXMoZnJvbSBhbm5vdGF0ZWQ6IFNvdXJjZXJ5UnVudGltZS5Bbm5vdGF0ZWQpIC0+IFtTdHJpbmddIHsKICAgICAgICBpZiBsZXQgdHlwZXMgPSBhbm5vdGF0ZWQuYW5ub3RhdGlvbnNbInR5cGVhbGlhcyJdIGFzPyBbU3RyaW5nXSB7CiAgICAgICAgICAgIHJldHVybiB0eXBlcy5yZXZlcnNlZCgpCiAgICAgICAgfSBlbHNlIGlmIGxldCB0eXBlID0gYW5ub3RhdGVkLmFubm90YXRpb25zWyJ0eXBlYWxpYXMiXSBhcz8gU3RyaW5nIHsKICAgICAgICAgICAgcmV0dXJuIFt0eXBlXQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBbXQogICAgICAgIH0KICAgIH0KICAgIHN0YXRpYyBmdW5jIGV4dHJhY3RHZW5lcmljc0xpc3QoXyBhc3NvY2lhdGVkVHlwZXM6IFtTdHJpbmddPykgLT4gW1N0cmluZ10gewogICAgICAgIHJldHVybiBhc3NvY2lhdGVkVHlwZXM/LmZsYXRNYXAgewogICAgICAgICAgICBzcGxpdCgkMCwgYnlGaXJzdE9jY3VyZW5jZU9mOiAiIHdoZXJlICIpLjAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICIgIiwgd2l0aDogIiIpLmNoYXJhY3RlcnMuc3BsaXQoc2VwYXJhdG9yOiAiOiIpLm1hcChTdHJpbmcuaW5pdCkuZmlyc3QKICAgICAgICB9Lm1hcCB7ICJcKCQwKSIgfSA/PyBbXQogICAgfQogICAgc3RhdGljIGZ1bmMgZXh0cmFjdEdlbmVyaWNUeXBlc01vZGlmaWVyKF8gYXNzb2NpYXRlZFR5cGVzOiBbU3RyaW5nXT8pIC0+IFN0cmluZyB7CiAgICAgICAgbGV0IGFsbCA9IGV4dHJhY3RHZW5lcmljc0xpc3QoYXNzb2NpYXRlZFR5cGVzKQogICAgICAgIGd1YXJkICFhbGwuaXNFbXB0eSBlbHNlIHsgcmV0dXJuICIiIH0KICAgICAgICByZXR1cm4gIjxcKGFsbC5qb2luZWQoc2VwYXJhdG9yOiAiLCIpKT4iCiAgICB9CiAgICBzdGF0aWMgZnVuYyBleHRyYWN0R2VuZXJpY1R5cGVzQ29uc3RyYWludHMoXyBhc3NvY2lhdGVkVHlwZXM6IFtTdHJpbmddPykgLT4gU3RyaW5nIHsKICAgICAgICBndWFyZCBsZXQgYWxsID0gYXNzb2NpYXRlZFR5cGVzIGVsc2UgeyByZXR1cm4gIiIgfQogICAgICAgIGxldCBjb25zdHJhaW50cyA9IGFsbC5mbGF0TWFwIHsgdCAtPiBTdHJpbmc/IGluCiAgICAgICAgICAgIGxldCBzcGxpdHRlZCA9IHNwbGl0KHQsIGJ5Rmlyc3RPY2N1cmVuY2VPZjogIiB3aGVyZSAiKQogICAgICAgICAgICBsZXQgY29uc3RyYWludCA9IHNwbGl0dGVkLjAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICIgIiwgd2l0aDogIiIpLmNoYXJhY3RlcnMuc3BsaXQoc2VwYXJhdG9yOiAiOiIpLm1hcChTdHJpbmcuaW5pdCkKICAgICAgICAgICAgZ3VhcmQgY29uc3RyYWludC5jb3VudCA9PSAyIGVsc2UgeyByZXR1cm4gbmlsIH0KICAgICAgICAgICAgbGV0IGFkb3B0cyA9IGNvbnN0cmFpbnRbMV0uY2hhcmFjdGVycy5zcGxpdChzZXBhcmF0b3I6ICIsIikubWFwKFN0cmluZy5pbml0KQogICAgICAgICAgICB2YXIgbWFwcGVkID0gYWRvcHRzLm1hcCB7ICJcKGNvbnN0cmFpbnRbMF0pOiBcKCQwKSIgfQogICAgICAgICAgICBpZiAhc3BsaXR0ZWQuMS5pc0VtcHR5IHsKICAgICAgICAgICAgICAgIG1hcHBlZC5hcHBlbmQoc3BsaXR0ZWQuMSkKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbWFwcGVkLmpvaW5lZChzZXBhcmF0b3I6ICIsICIpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgLmpvaW5lZChzZXBhcmF0b3I6ICIsICIpCiAgICAgICAgZ3VhcmQgIWNvbnN0cmFpbnRzLmlzRW1wdHkgZWxzZSB7IHJldHVybiAiIiB9CiAgICAgICAgcmV0dXJuICIgd2hlcmUgXChjb25zdHJhaW50cykiCiAgICB9CiAgICBzdGF0aWMgZnVuYyBleHRyYWN0QXR0cmlidXRlcygKICAgICAgICBmcm9tIGF0dHJpYnV0ZXM6IFtTdHJpbmc6IFtTb3VyY2VyeVJ1bnRpbWUuQXR0cmlidXRlXV0sCiAgICAgICAgZmlsdGVyT3V0U3RhcnRpbmdXaXRoIGRpc2FsbG93ZWRQcmVmaXhlczogW1N0cmluZ10gPSBbXQogICAgKSAtPiBTdHJpbmcgewogICAgICAgIHJldHVybiBhdHRyaWJ1dGVzCiAgICAgICAgLnJlZHVjZShbU291cmNlcnlSdW50aW1lLkF0dHJpYnV0ZV0oKSkgeyAkMCArICQxLjEgfQogICAgICAgIC5tYXAgeyAkMC5kZXNjcmlwdGlvbiB9CiAgICAgICAgLmZpbHRlciB7ICFbInByaXZhdGUiLCAiaW50ZXJuYWwiLCAicHVibGljIiwgIm9wZW4iLCAib3B0aW9uYWwiXS5jb250YWlucygkMCkgfQogICAgICAgIC5maWx0ZXIgeyBlbGVtZW50IGluCiAgICAgICAgICAgICFkaXNhbGxvd2VkUHJlZml4ZXMuY29udGFpbnMod2hlcmU6IGVsZW1lbnQuaGFzUHJlZml4KQogICAgICAgIH0KICAgICAgICAuc29ydGVkKCkKICAgICAgICAuam9pbmVkKHNlcGFyYXRvcjogIiAiKQogICAgfQp9CmNsYXNzIFBhcmFtZXRlcldyYXBwZXIgewogICAgbGV0IHBhcmFtZXRlcjogTWV0aG9kUGFyYW1ldGVyCgogICAgdmFyIGlzVmFyaWFkaWMgPSBmYWxzZQoKICAgIHZhciB3cmFwcGVkRm9yQ2FsbDogU3RyaW5nIHsKICAgICAgICBsZXQgdHlwZVN0cmluZyA9ICJcKHR5cGUuYWN0dWFsVHlwZU5hbWUgPz8gdHlwZSkiCiAgICAgICAgbGV0IGlzRXNjYXBpbmcgPSB0eXBlU3RyaW5nLmNvbnRhaW5zKCJAZXNjYXBpbmciKQogICAgICAgIGxldCBpc09wdGlvbmFsID0gKHR5cGUuYWN0dWFsVHlwZU5hbWUgPz8gdHlwZSkuaXNPcHRpb25hbAogICAgICAgIGlmIHBhcmFtZXRlci5pc0Nsb3N1cmUgJiYgIWlzRXNjYXBpbmcgJiYgIWlzT3B0aW9uYWwgewogICAgICAgICAgICByZXR1cm4gIlwobmVzdGVkVHlwZSkuYW55IgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAiXChuZXN0ZWRUeXBlKS52YWx1ZShcKGVzY2FwZWROYW1lKSkiCiAgICAgICAgfQogICAgfQogICAgdmFyIG5lc3RlZFR5cGU6IFN0cmluZyB7CiAgICAgICAgcmV0dXJuICJcKFR5cGVXcmFwcGVyKHR5cGUsIGlzVmFyaWFkaWMpLm5lc3RlZFBhcmFtZXRlcikiCiAgICB9CiAgICB2YXIganVzdFR5cGU6IFN0cmluZyB7CiAgICAgICAgcmV0dXJuICJcKFR5cGVXcmFwcGVyKHR5cGUsIGlzVmFyaWFkaWMpLnJlcGxhY2luZ1NlbGYoKSkiCiAgICB9CiAgICB2YXIganVzdFBlcmZvcm1UeXBlOiBTdHJpbmcgewogICAgICAgIHJldHVybiAiXChUeXBlV3JhcHBlcih0eXBlLCBpc1ZhcmlhZGljKS5yZXBsYWNpbmdTZWxmUmVzcGVjdGluZ1ZhcmlhZGljKCkpIi5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogIiEiLCB3aXRoOiAiPyIpCiAgICB9CiAgICB2YXIgZ2VuZXJpY1R5cGU6IFN0cmluZyB7CiAgICAgICAgcmV0dXJuIGlzVmFyaWFkaWMgPyAiUGFyYW1ldGVyPFtHZW5lcmljQXR0cmlidXRlXT4iIDogIlBhcmFtZXRlcjxHZW5lcmljQXR0cmlidXRlPiIKICAgIH0KICAgIHZhciB0eXBlRXJhc2VkVHlwZTogU3RyaW5nIHsKICAgICAgICByZXR1cm4gaXNWYXJpYWRpYyA/ICJQYXJhbWV0ZXI8W1R5cGVFcmFzZWRBdHRyaWJ1dGVdPiIgOiAiUGFyYW1ldGVyPFR5cGVFcmFzZWRBdHRyaWJ1dGU+IgogICAgfQogICAgdmFyIHR5cGU6IFNvdXJjZXJ5UnVudGltZS5UeXBlTmFtZSB7CiAgICAgICAgcmV0dXJuIHBhcmFtZXRlci50eXBlTmFtZQogICAgfQogICAgdmFyIG5hbWU6IFN0cmluZyB7CiAgICAgICAgcmV0dXJuIHBhcmFtZXRlci5uYW1lCiAgICB9CiAgICB2YXIgZXNjYXBlZE5hbWU6IFN0cmluZyB7CiAgICAgICAgcmV0dXJuICJgXChwYXJhbWV0ZXIubmFtZSlgIgogICAgfQogICAgdmFyIGNvbXBhcmF0b3I6IFN0cmluZyB7CiAgICAgICAgcmV0dXJuICJndWFyZCBQYXJhbWV0ZXIuY29tcGFyZShsaHM6IGxoc1wocGFyYW1ldGVyLm5hbWUuY2FwaXRhbGl6ZWQpLCByaHM6IHJoc1wocGFyYW1ldGVyLm5hbWUuY2FwaXRhbGl6ZWQpLCB3aXRoOiBtYXRjaGVyKSBlbHNlIHsgcmV0dXJuIGZhbHNlIH0iCiAgICB9CiAgICBmdW5jIGNvbXBhcmF0b3JSZXN1bHQoKSAtPiBTdHJpbmcgewogICAgICAgIGxldCBsaHNOYW1lID0gImxoc1wocGFyYW1ldGVyLm5hbWUuY2FwaXRhbGl6ZWQpIgogICAgICAgIGxldCByaHNOYW1lID0gInJoc1wocGFyYW1ldGVyLm5hbWUuY2FwaXRhbGl6ZWQpIgogICAgICAgIHJldHVybiAicmVzdWx0cy5hcHBlbmQoTWF0Y2hlci5QYXJhbWV0ZXJDb21wYXJpc29uUmVzdWx0KFBhcmFtZXRlci5jb21wYXJlKGxoczogXChsaHNOYW1lKSwgcmhzOiBcKHJoc05hbWUpLCB3aXRoOiBtYXRjaGVyKSwgXChsaHNOYW1lKSwgXChyaHNOYW1lKSwgXCJcKGxhYmVsQW5kTmFtZSgpKVwiKSkiCiAgICB9CgogICAgaW5pdChfIHBhcmFtZXRlcjogU291cmNlcnlSdW50aW1lLk1ldGhvZFBhcmFtZXRlciwgXyB2YXJpYWRpY3M6IFtTdHJpbmddID0gW10pIHsKICAgICAgICBzZWxmLnBhcmFtZXRlciA9IHBhcmFtZXRlcgogICAgICAgIHNlbGYuaXNWYXJpYWRpYyA9ICF2YXJpYWRpY3MuaXNFbXB0eSAmJiB2YXJpYWRpY3MuY29udGFpbnMocGFyYW1ldGVyLm5hbWUpCiAgICB9CgogICAgZnVuYyBpc0dlbmVyaWMoXyB0eXBlczogW1N0cmluZ10pIC0+IEJvb2wgewogICAgICAgIHJldHVybiBUeXBlV3JhcHBlcih0eXBlKS5pc0dlbmVyaWModHlwZXMpCiAgICB9CgogICAgZnVuYyB3cmFwcGVkRm9yUHJveHkoXyBnZW5lcmljczogW1N0cmluZ10sIF8gYXZhaWxhYmlsaXR5OiBCb29sID0gZmFsc2UpIC0+IFN0cmluZyB7CiAgICAgICAgaWYgaXNHZW5lcmljKGdlbmVyaWNzKSB7CiAgICAgICAgICAgIHJldHVybiAiXChlc2NhcGVkTmFtZSkud3JhcEFzR2VuZXJpYygpIgogICAgICAgIH0KICAgICAgICBpZiAoYXZhaWxhYmlsaXR5KSB7CiAgICAgICAgICAgIHJldHVybiAiXChlc2NhcGVkTmFtZSkudHlwZUVyYXNlZEF0dHJpYnV0ZSgpIgogICAgICAgIH0KICAgICAgICByZXR1cm4gIlwoZXNjYXBlZE5hbWUpIgogICAgfQogICAgZnVuYyB3cmFwcGVkRm9yQ2FsbHMoXyBnZW5lcmljczogW1N0cmluZ10sIF8gYXZhaWxhYmlsaXR5OiBCb29sID0gZmFsc2UpIC0+IFN0cmluZyB7CiAgICAgICAgaWYgaXNHZW5lcmljKGdlbmVyaWNzKSB7CiAgICAgICAgICAgIHJldHVybiAiXCh3cmFwcGVkRm9yQ2FsbCkud3JhcEFzR2VuZXJpYygpIgogICAgICAgIH0KICAgICAgICBpZiAoYXZhaWxhYmlsaXR5KSB7CiAgICAgICAgICAgIHJldHVybiAiXCh3cmFwcGVkRm9yQ2FsbCkudHlwZUVyYXNlZEF0dHJpYnV0ZSgpIgogICAgICAgIH0KICAgICAgICByZXR1cm4gIlwod3JhcHBlZEZvckNhbGwpIgogICAgfQoKICAgIGZ1bmMgYXNNZXRob2RBcmd1bWVudCgpIC0+IFN0cmluZyB7CiAgICAgICAgaWYgcGFyYW1ldGVyLmFyZ3VtZW50TGFiZWwgIT0gcGFyYW1ldGVyLm5hbWUgewogICAgICAgICAgICByZXR1cm4gIlwocGFyYW1ldGVyLmFyZ3VtZW50TGFiZWwgPz8gIl8iKSBcKHBhcmFtZXRlci5uYW1lKTogXChwYXJhbWV0ZXIudHlwZU5hbWUpIgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAiXChwYXJhbWV0ZXIubmFtZSk6IFwocGFyYW1ldGVyLnR5cGVOYW1lKSIKICAgICAgICB9CiAgICB9CiAgICBmdW5jIGxhYmVsQW5kTmFtZSgpIC0+IFN0cmluZyB7CiAgICAgICAgbGV0IGxhYmVsID0gcGFyYW1ldGVyLmFyZ3VtZW50TGFiZWwgPz8gIl8iCiAgICAgICAgcmV0dXJuIGxhYmVsICE9IHBhcmFtZXRlci5uYW1lID8gIlwobGFiZWwpIFwocGFyYW1ldGVyLm5hbWUpIiA6IGxhYmVsCiAgICB9CiAgICBmdW5jIHNhbml0aXplZEZvckVudW1DYXNlTmFtZSgpIC0+IFN0cmluZyB7CiAgICAgICAgaWYgbGV0IGxhYmVsID0gcGFyYW1ldGVyLmFyZ3VtZW50TGFiZWwsIGxhYmVsICE9IHBhcmFtZXRlci5uYW1lIHsKICAgICAgICAgICAgcmV0dXJuICJcKGxhYmVsKV9cKHBhcmFtZXRlci5uYW1lKSIucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICJgIiwgd2l0aDogIiIpCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuICJcKHBhcmFtZXRlci5uYW1lKSIucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICJgIiwgd2l0aDogIiIpCiAgICAgICAgfQogICAgfQp9CmNsYXNzIFR5cGVXcmFwcGVyIHsKICAgIGxldCB0eXBlOiBTb3VyY2VyeVJ1bnRpbWUuVHlwZU5hbWUKICAgIGxldCBpc1ZhcmlhZGljOiBCb29sCgogICAgdmFyIHZQcmVmOiBTdHJpbmcgeyByZXR1cm4gaXNWYXJpYWRpYyA/ICJbIiA6ICIiIH0KICAgIHZhciB2U3VmZjogU3RyaW5nIHsgcmV0dXJuIGlzVmFyaWFkaWMgPyAiXSIgOiAiIiB9CgogICAgdmFyIHVud3JhcHBlZDogU3RyaW5nIHsKICAgICAgICByZXR1cm4gdHlwZS51bndyYXBwZWRUeXBlTmFtZQogICAgfQogICAgdmFyIHVud3JhcHBlZFJlcGxhY2luZ1NlbGY6IFN0cmluZyB7CiAgICAgICAgcmV0dXJuIHJlcGxhY2luZ1NlbGYodW53cmFwOiB0cnVlKQogICAgfQogICAgdmFyIHN0cmlwcGVkOiBTdHJpbmcgewogICAgICAgIGlmIHR5cGUuaXNJbXBsaWNpdGx5VW53cmFwcGVkT3B0aW9uYWwgewogICAgICAgICAgICByZXR1cm4gIlwodlByZWYpXCh1bndyYXBwZWRSZXBsYWNpbmdTZWxmKT9cKHZTdWZmKSIKICAgICAgICB9IGVsc2UgaWYgdHlwZS5pc09wdGlvbmFsIHsKICAgICAgICAgICAgcmV0dXJuICJcKHZQcmVmKVwodW53cmFwcGVkUmVwbGFjaW5nU2VsZik/XCh2U3VmZikiCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuICJcKHZQcmVmKVwodW53cmFwcGVkUmVwbGFjaW5nU2VsZilcKHZTdWZmKSIKICAgICAgICB9CiAgICB9CiAgICB2YXIgbmVzdGVkUGFyYW1ldGVyOiBTdHJpbmcgewogICAgICAgIGlmIHR5cGUuaXNJbXBsaWNpdGx5VW53cmFwcGVkT3B0aW9uYWwgewogICAgICAgICAgICByZXR1cm4gIlBhcmFtZXRlcjxcKHZQcmVmKVwodW53cmFwcGVkUmVwbGFjaW5nU2VsZik/XCh2U3VmZik+IgogICAgICAgIH0gZWxzZSBpZiB0eXBlLmlzT3B0aW9uYWwgewogICAgICAgICAgICByZXR1cm4gIlBhcmFtZXRlcjxcKHZQcmVmKVwodW53cmFwcGVkUmVwbGFjaW5nU2VsZik/XCh2U3VmZik+IgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAiUGFyYW1ldGVyPFwodlByZWYpXCh1bndyYXBwZWRSZXBsYWNpbmdTZWxmKVwodlN1ZmYpPiIKICAgICAgICB9CiAgICB9CiAgICB2YXIgaXNTZWxmVHlwZTogQm9vbCB7CiAgICAgICAgcmV0dXJuIHVud3JhcHBlZCA9PSAiU2VsZiIKICAgIH0KICAgIGZ1bmMgaXNTZWxmVHlwZVJlY3Vyc2l2ZSgpIC0+IEJvb2wgewogICAgICAgIGlmIGxldCB0dXBsZSA9IHR5cGUudHVwbGUgewogICAgICAgICAgICBmb3IgZWxlbWVudCBpbiB0dXBsZS5lbGVtZW50cyB7CiAgICAgICAgICAgICAgICBndWFyZCAhVHlwZVdyYXBwZXIoZWxlbWVudC50eXBlTmFtZSkuaXNTZWxmVHlwZVJlY3Vyc2l2ZSgpIGVsc2UgeyByZXR1cm4gdHJ1ZSB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgbGV0IGFycmF5ID0gdHlwZS5hcnJheSB7CiAgICAgICAgICAgIHJldHVybiBUeXBlV3JhcHBlcihhcnJheS5lbGVtZW50VHlwZU5hbWUpLmlzU2VsZlR5cGVSZWN1cnNpdmUoKQogICAgICAgIH0gZWxzZSBpZiBsZXQgZGljdGlvbmFyeSA9IHR5cGUuZGljdGlvbmFyeSB7CiAgICAgICAgICAgIGd1YXJkICFUeXBlV3JhcHBlcihkaWN0aW9uYXJ5LnZhbHVlVHlwZU5hbWUpLmlzU2VsZlR5cGVSZWN1cnNpdmUoKSBlbHNlIHsgcmV0dXJuIHRydWUgfQogICAgICAgICAgICBndWFyZCAhVHlwZVdyYXBwZXIoZGljdGlvbmFyeS5rZXlUeXBlTmFtZSkuaXNTZWxmVHlwZVJlY3Vyc2l2ZSgpIGVsc2UgeyByZXR1cm4gdHJ1ZSB9CiAgICAgICAgfSBlbHNlIGlmIGxldCBjbG9zdXJlID0gdHlwZS5jbG9zdXJlIHsKICAgICAgICAgICAgZ3VhcmQgIVR5cGVXcmFwcGVyKGNsb3N1cmUuYWN0dWFsUmV0dXJuVHlwZU5hbWUpLmlzU2VsZlR5cGVSZWN1cnNpdmUoKSBlbHNlIHsgcmV0dXJuIHRydWUgfQogICAgICAgICAgICBmb3IgcGFyYW1ldGVyIGluIGNsb3N1cmUucGFyYW1ldGVycyB7CiAgICAgICAgICAgICAgICBndWFyZCAhVHlwZVdyYXBwZXIocGFyYW1ldGVyLnR5cGVOYW1lKS5pc1NlbGZUeXBlUmVjdXJzaXZlKCkgZWxzZSB7IHJldHVybiB0cnVlIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGlzU2VsZlR5cGUKICAgIH0KCiAgICBpbml0KF8gdHlwZTogU291cmNlcnlSdW50aW1lLlR5cGVOYW1lLCBfIGlzVmFyaWFkaWM6IEJvb2wgPSBmYWxzZSkgewogICAgICAgIHNlbGYudHlwZSA9IHR5cGUKICAgICAgICBzZWxmLmlzVmFyaWFkaWMgPSBpc1ZhcmlhZGljCiAgICB9CgogICAgZnVuYyBpc0dlbmVyaWMoXyB0eXBlczogW1N0cmluZ10pIC0+IEJvb2wgewogICAgICAgIGd1YXJkICF0eXBlLmlzVm9pZCBlbHNlIHsgcmV0dXJuIGZhbHNlIH0KCiAgICAgICAgcmV0dXJuIGlzR2VuZXJpYyhuYW1lOiB1bndyYXBwZWQsIGdlbmVyaWNzOiB0eXBlcykKICAgIH0KCiAgICBwcml2YXRlIGZ1bmMgaXNHZW5lcmljKG5hbWU6IFN0cmluZywgZ2VuZXJpY3M6IFtTdHJpbmddKSAtPiBCb29sIHsKICAgICAgICBsZXQgbmFtZSA9ICIoXChuYW1lLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiICIsIHdpdGg6ICIiKSkpIgogICAgICAgIGxldCBtb2RpZmllcnMgPSAiW1xcP1xcIV0qIgogICAgICAgIHJldHVybiBnZW5lcmljcy5jb250YWlucyh3aGVyZTogeyBnZW5lcmljIGluCiAgICAgICAgICAgIGxldCB3cmFwcGVkID0gIihbXFwoXVwoZ2VuZXJpYylcKG1vZGlmaWVycylbXFwpXFwuXSkiCiAgICAgICAgICAgIGxldCBjb25zdHJhaW50ID0gIihbPCxdXChnZW5lcmljKVwobW9kaWZpZXJzKVs+LFxcLl0pIgogICAgICAgICAgICBsZXQgYXJyYXlzID0gIihbXFxbOl1cKGdlbmVyaWMpXChtb2RpZmllcnMpW1xcXSxcXC46XSkiCiAgICAgICAgICAgIGxldCB0dXBsZXMgPSAiKFtcXCgsXVwoZ2VuZXJpYylcKG1vZGlmaWVycylbLFxcLlxcKV0pIgogICAgICAgICAgICBsZXQgY2xvc3VyZXMgPSAiKChcXC1cXD4pXChnZW5lcmljKVwobW9kaWZpZXJzKVssXFwuXFwpXSkiCiAgICAgICAgICAgIGxldCBwYXR0ZXJuID0gIlwod3JhcHBlZCl8XChjb25zdHJhaW50KXxcKGFycmF5cyl8XCh0dXBsZXMpfFwoY2xvc3VyZXMpIgogICAgICAgICAgICBndWFyZCBsZXQgcmVnZXggPSB0cnk/IE5TUmVndWxhckV4cHJlc3Npb24ocGF0dGVybjogcGF0dGVybikgZWxzZSB7IHJldHVybiBmYWxzZSB9CiAgICAgICAgICAgIHJldHVybiByZWdleC5maXJzdE1hdGNoKGluOiBuYW1lLCBvcHRpb25zOiBbXSwgcmFuZ2U6IE5TUmFuZ2UobG9jYXRpb246IDAsIGxlbmd0aDogKG5hbWUgYXMgTlNTdHJpbmcpLmxlbmd0aCkpICE9IG5pbAogICAgICAgIH0pCiAgICB9CgogICAgZnVuYyByZXBsYWNpbmdTZWxmKHVud3JhcDogQm9vbCA9IGZhbHNlKSAtPiBTdHJpbmcgewogICAgICAgIGd1YXJkIGlzU2VsZlR5cGVSZWN1cnNpdmUoKSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIHVud3JhcCA/IHNlbGYudW53cmFwcGVkIDogIlwodHlwZSkiCiAgICAgICAgfQoKICAgICAgICBpZiBpc1NlbGZUeXBlIHsKICAgICAgICAgICAgbGV0IG9wdGlvbmFsaXR5OiBTdHJpbmcgPSB7CiAgICAgICAgICAgICAgICBpZiB0eXBlLmlzSW1wbGljaXRseVVud3JhcHBlZE9wdGlvbmFsIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gIiEiCiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgdHlwZS5pc09wdGlvbmFsIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gIj8iCiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAiIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KCkKICAgICAgICAgICAgcmV0dXJuIHVud3JhcCA/IEN1cnJlbnQuc2VsZlR5cGUgOiBDdXJyZW50LnNlbGZUeXBlICsgb3B0aW9uYWxpdHkKICAgICAgICB9IGVsc2UgaWYgbGV0IHR1cGxlID0gdHlwZS50dXBsZSB7CiAgICAgICAgICAgIGxldCBpbm5lciA9IHR1cGxlLmVsZW1lbnRzLm1hcCh7IFR5cGVXcmFwcGVyKCQwLnR5cGVOYW1lKS5yZXBsYWNpbmdTZWxmKCkgfSkuam9pbmVkKHNlcGFyYXRvcjogIiwiKQogICAgICAgICAgICBsZXQgdmFsdWUgPSAiKFwoaW5uZXIpKSIKICAgICAgICAgICAgcmV0dXJuIHZhbHVlCiAgICAgICAgfSBlbHNlIGlmIGxldCBhcnJheSA9IHR5cGUuYXJyYXkgewogICAgICAgICAgICBsZXQgdmFsdWUgPSAiW1woVHlwZVdyYXBwZXIoYXJyYXkuZWxlbWVudFR5cGVOYW1lKS5yZXBsYWNpbmdTZWxmKCkpXSIKICAgICAgICAgICAgcmV0dXJuIHZhbHVlCiAgICAgICAgfSBlbHNlIGlmIGxldCBkaWN0aW9uYXJ5ID0gdHlwZS5kaWN0aW9uYXJ5IHsKICAgICAgICAgICAgbGV0IHZhbHVlID0gIlsiICsKICAgICAgICAgICAgICAgICJcKFR5cGVXcmFwcGVyKGRpY3Rpb25hcnkudmFsdWVUeXBlTmFtZSkucmVwbGFjaW5nU2VsZigpKSIKICAgICAgICAgICAgICAgICsgIjoiICsKICAgICAgICAgICAgICAgICJcKFR5cGVXcmFwcGVyKGRpY3Rpb25hcnkua2V5VHlwZU5hbWUpLnJlcGxhY2luZ1NlbGYoKSkiCiAgICAgICAgICAgICAgICArICJdIgogICAgICAgICAgICByZXR1cm4gdmFsdWUKICAgICAgICB9IGVsc2UgaWYgbGV0IGNsb3N1cmUgPSB0eXBlLmNsb3N1cmUgewogICAgICAgICAgICBsZXQgcmV0dXJuVHlwZSA9IFR5cGVXcmFwcGVyKGNsb3N1cmUuYWN0dWFsUmV0dXJuVHlwZU5hbWUpLnJlcGxhY2luZ1NlbGYoKQogICAgICAgICAgICBsZXQgaW5uZXIgPSBjbG9zdXJlLnBhcmFtZXRlcnMKICAgICAgICAgICAgICAgIC5tYXAgeyBUeXBlV3JhcHBlcigkMC50eXBlTmFtZSkucmVwbGFjaW5nU2VsZigpIH0KICAgICAgICAgICAgICAgIC5qb2luZWQoc2VwYXJhdG9yOiAiLCIpCiAgICAgICAgICAgIGxldCB0aHJvd2luZyA9IGNsb3N1cmUudGhyb3dzID8gInRocm93cyAiIDogIiIKICAgICAgICAgICAgbGV0IHZhbHVlID0gIihcKGlubmVyKSkgXCh0aHJvd2luZyktPiBcKHJldHVyblR5cGUpIgogICAgICAgICAgICByZXR1cm4gdmFsdWUKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gKHVud3JhcCA/IHNlbGYudW53cmFwcGVkIDogIlwodHlwZSkiKQogICAgICAgIH0KICAgIH0KCiAgICBmdW5jIHJlcGxhY2luZ1NlbGZSZXNwZWN0aW5nVmFyaWFkaWMoKSAtPiBTdHJpbmcgewogICAgICAgIHJldHVybiAiXCh2UHJlZilcKHJlcGxhY2luZ1NlbGYoKSlcKHZTdWZmKSIKICAgIH0KfQpmdW5jIHJlcGxhY2luZ1NlbGYoXyB2YWx1ZTogU3RyaW5nKSAtPiBTdHJpbmcgewogICAgcmV0dXJuIHZhbHVlCiAgICAgICAgLy8gVE9ETzogcHJvcGVyIHJlZ2V4IGhlcmUKICAgICAgICAvLyBkZWZhdWx0IDwgY2FzZSA+CiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiPFNlbGY+Iiwgd2l0aDogIjxcKEN1cnJlbnQuc2VsZlR5cGUpPiIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiPFNlbGYgIiwgd2l0aDogIjxcKEN1cnJlbnQuc2VsZlR5cGUpICIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiPFNlbGYuIiwgd2l0aDogIjxcKEN1cnJlbnQuc2VsZlR5cGUpLiIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiPFNlbGYsIiwgd2l0aDogIjxcKEN1cnJlbnQuc2VsZlR5cGUpLCIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiPFNlbGY/Iiwgd2l0aDogIjxcKEN1cnJlbnQuc2VsZlR5cGUpPyIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiIFNlbGY+Iiwgd2l0aDogIiBcKEN1cnJlbnQuc2VsZlR5cGUpPiIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiLFNlbGY+Iiwgd2l0aDogIixcKEN1cnJlbnQuc2VsZlR5cGUpPiIpCiAgICAgICAgLy8gKFNlbGYpIC0+IENhc2UKICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICIoU2VsZikiLCB3aXRoOiAiKFwoQ3VycmVudC5zZWxmVHlwZSkpIikKICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICIoU2VsZiAiLCB3aXRoOiAiKFwoQ3VycmVudC5zZWxmVHlwZSkgIikKICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICIoU2VsZi4iLCB3aXRoOiAiKFwoQ3VycmVudC5zZWxmVHlwZSkuIikKICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICIoU2VsZiwiLCB3aXRoOiAiKFwoQ3VycmVudC5zZWxmVHlwZSksIikKICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICIoU2VsZj8iLCB3aXRoOiAiKFwoQ3VycmVudC5zZWxmVHlwZSk/IikKICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICIgU2VsZikiLCB3aXRoOiAiIFwoQ3VycmVudC5zZWxmVHlwZSkpIikKICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICIsU2VsZikiLCB3aXRoOiAiLFwoQ3VycmVudC5zZWxmVHlwZSkpIikKICAgICAgICAvLyBsaXRlcmFscwogICAgICAgIC5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogIltTZWxmXSIsIHdpdGg6ICJbXChDdXJyZW50LnNlbGZUeXBlKV0iKQogICAgICAgIC8vIHJpZ2h0CiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiW1NlbGYgIiwgd2l0aDogIltcKEN1cnJlbnQuc2VsZlR5cGUpICIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiW1NlbGYuIiwgd2l0aDogIltcKEN1cnJlbnQuc2VsZlR5cGUpLiIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiW1NlbGYsIiwgd2l0aDogIltcKEN1cnJlbnQuc2VsZlR5cGUpLCIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiW1NlbGY6Iiwgd2l0aDogIltcKEN1cnJlbnQuc2VsZlR5cGUpOiIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiW1NlbGY/Iiwgd2l0aDogIltcKEN1cnJlbnQuc2VsZlR5cGUpPyIpCiAgICAgICAgLy8gbGVmdAogICAgICAgIC5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogIiBTZWxmXSIsIHdpdGg6ICIgXChDdXJyZW50LnNlbGZUeXBlKV0iKQogICAgICAgIC5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogIixTZWxmXSIsIHdpdGg6ICIsXChDdXJyZW50LnNlbGZUeXBlKV0iKQogICAgICAgIC5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogIjpTZWxmXSIsIHdpdGg6ICI6XChDdXJyZW50LnNlbGZUeXBlKV0iKQogICAgICAgIC8vIHVua25vd24KICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICIgU2VsZiAiLCB3aXRoOiAiIFwoQ3VycmVudC5zZWxmVHlwZSkgIikKICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICIgU2VsZi4iLCB3aXRoOiAiIFwoQ3VycmVudC5zZWxmVHlwZSkuIikKICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICIgU2VsZiwiLCB3aXRoOiAiIFwoQ3VycmVudC5zZWxmVHlwZSksIikKICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICIgU2VsZjoiLCB3aXRoOiAiIFwoQ3VycmVudC5zZWxmVHlwZSk6IikKICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICIgU2VsZj8iLCB3aXRoOiAiIFwoQ3VycmVudC5zZWxmVHlwZSk/IikKICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICIsU2VsZiAiLCB3aXRoOiAiLFwoQ3VycmVudC5zZWxmVHlwZSkgIikKICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICIsU2VsZiwiLCB3aXRoOiAiLFwoQ3VycmVudC5zZWxmVHlwZSksIikKICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICIsU2VsZj8iLCB3aXRoOiAiLFwoQ3VycmVudC5zZWxmVHlwZSk/IikKfQoKY2xhc3MgTWV0aG9kV3JhcHBlciB7CiAgICBwcml2YXRlIHZhciBub1N0dWJEZWZpbmVkTWVzc2FnZTogU3RyaW5nIHsKICAgICAgICBsZXQgbWV0aG9kTmFtZSA9IG1ldGhvZC5uYW1lLmNvbmRlbnNlV2hpdGVzcGFjZSgpCiAgICAgICAgICAgIC5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogIiggIiwgd2l0aDogIigiKQogICAgICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICIgKSIsIHdpdGg6ICIpIikKICAgICAgICByZXR1cm4gIlN0dWIgcmV0dXJuIHZhbHVlIG5vdCBzcGVjaWZpZWQgZm9yIFwobWV0aG9kTmFtZSkuIFVzZSBnaXZlbiIKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIHZhciByZWdpc3RlcmVkOiBbU3RyaW5nOiBJbnRdID0gWzpdCiAgICBwcml2YXRlIHN0YXRpYyB2YXIgc3VmZml4ZXM6IFtTdHJpbmc6IEludF0gPSBbOl0KICAgIHByaXZhdGUgc3RhdGljIHZhciBzdWZmaXhlc1dpdGhvdXRSZXR1cm5UeXBlOiBbU3RyaW5nOiBJbnRdID0gWzpdCgogICAgbGV0IG1ldGhvZDogU291cmNlcnlSdW50aW1lLk1ldGhvZAogICAgdmFyIGFjY2Vzc01vZGlmaWVyOiBTdHJpbmcgewogICAgICAgIGd1YXJkICFtZXRob2QuaXNTdGF0aWMgZWxzZSB7IHJldHVybiAicHVibGljIHN0YXRpYyIgfQogICAgICAgIGd1YXJkICFyZXR1cm5zR2VuZXJpY0NvbnN0cmFpbmVkVG9TZWxmIGVsc2UgeyByZXR1cm4gInB1YmxpYyIgfQogICAgICAgIGd1YXJkICFwYXJhbWV0ZXJzQ29udGFpbnNTZWxmIGVsc2UgeyByZXR1cm4gInB1YmxpYyIgfQogICAgICAgIHJldHVybiBDdXJyZW50LmFjY2Vzc01vZGlmaWVyCiAgICB9CiAgICB2YXIgaGFzQXZhaWxhYmlsaXR5OiBCb29sIHsgbWV0aG9kLmF0dHJpYnV0ZXNbImF2YWlsYWJsZSJdPy5pc0VtcHR5ID09IGZhbHNlIH0KICAgIHZhciBpc0FzeW5jOiBCb29sIHsKICAgICAgICBzZWxmLm1ldGhvZC5hbm5vdGF0aW9uc1siYXN5bmMiXSAhPSBuaWwKICAgIH0KCiAgICBwcml2YXRlIHZhciByZWdpc3RyYXRpb25OYW1lOiBTdHJpbmcgewogICAgICAgIHZhciByYXdOYW1lID0gKG1ldGhvZC5pc1N0YXRpYyA/ICJzbSpcKG1ldGhvZC5zZWxlY3Rvck5hbWUpIiA6ICJtKlwobWV0aG9kLnNlbGVjdG9yTmFtZSkiKQogICAgICAgIC5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogIl8iLCB3aXRoOiAiIikKICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICIoIiwgd2l0aDogIl9fIikKICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICIpIiwgd2l0aDogIiIpCgogICAgICAgIHZhciBwYXJhbWV0ZXJzTmFtZXMgPSBtZXRob2QucGFyYW1ldGVycy5tYXAgeyAiXCgkMC5uYW1lKSIgfQoKICAgICAgICB3aGlsZSBsZXQgcmFuZ2UgPSByYXdOYW1lLnJhbmdlKG9mOiAiOiIpLCBsZXQgbmFtZSA9IHBhcmFtZXRlcnNOYW1lcy5maXJzdCB7CiAgICAgICAgICAgIHBhcmFtZXRlcnNOYW1lcy5yZW1vdmVGaXJzdCgpCiAgICAgICAgICAgIHJhd05hbWUucmVwbGFjZVN1YnJhbmdlKHJhbmdlLCB3aXRoOiAiX1wobmFtZSkiKQogICAgICAgIH0KCiAgICAgICAgbGV0IHRyaW1TZXQgPSBDaGFyYWN0ZXJTZXQoY2hhcmFjdGVyc0luOiAiXyIpCgogICAgICAgIHJldHVybiAgcmF3TmFtZQogICAgICAgIC5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogIjoiLCB3aXRoOiAiIikKICAgICAgICAucmVwbGFjaW5nT2NjdXJyZW5jZXMob2Y6ICJtKiIsIHdpdGg6ICJtXyIpCiAgICAgICAgLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiX19fIiwgd2l0aDogIl9fIikudHJpbW1pbmdDaGFyYWN0ZXJzKGluOiB0cmltU2V0KQogICAgfQogICAgcHJpdmF0ZSB2YXIgdW5pcXVlTmFtZTogU3RyaW5nIHsKICAgICAgICB2YXIgcmF3TmFtZSA9IChtZXRob2QuaXNTdGF0aWMgPyAic21fXChtZXRob2Quc2VsZWN0b3JOYW1lKSIgOiAibV9cKG1ldGhvZC5zZWxlY3Rvck5hbWUpIikKICAgICAgICB2YXIgcGFyYW1ldGVyc05hbWVzID0gbWV0aG9kLnBhcmFtZXRlcnMubWFwIHsgIlwoJDAubmFtZSlfb2ZfXCgkMC50eXBlTmFtZS5uYW1lKSIgfQoKICAgICAgICB3aGlsZSBsZXQgcmFuZ2UgPSByYXdOYW1lLnJhbmdlKG9mOiAiOiIpLCBsZXQgbmFtZSA9IHBhcmFtZXRlcnNOYW1lcy5maXJzdCB7CiAgICAgICAgICAgIHBhcmFtZXRlcnNOYW1lcy5yZW1vdmVGaXJzdCgpCiAgICAgICAgICAgIHJhd05hbWUucmVwbGFjZVN1YnJhbmdlKHJhbmdlLCB3aXRoOiAiX1wobmFtZSkiKQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHJhd05hbWUudHJpbW1pbmdDaGFyYWN0ZXJzKGluOiBDaGFyYWN0ZXJTZXQoY2hhcmFjdGVyc0luOiAiXyIpKQogICAgfQogICAgcHJpdmF0ZSB2YXIgdW5pcXVlTmFtZVdpdGhSZXR1cm5UeXBlOiBTdHJpbmcgewogICAgICAgIGxldCByZXR1cm5UeXBlUmF3ID0gIlwobWV0aG9kLnJldHVyblR5cGVOYW1lKSIKICAgICAgICB2YXIgcmV0dXJuVHlwZVN0cmlwcGVkOiBTdHJpbmcgPSB7CiAgICAgICAgICAgIGd1YXJkIGxldCByYW5nZSA9IHJldHVyblR5cGVSYXcucmFuZ2Uob2Y6ICJ3aGVyZSIpIGVsc2UgeyByZXR1cm4gcmV0dXJuVHlwZVJhdyB9CiAgICAgICAgICAgIHZhciBzdHJpcHBlZCA9IHJldHVyblR5cGVSYXcKICAgICAgICAgICAgc3RyaXBwZWQucmVtb3ZlU3VicmFuZ2UoKHJhbmdlLmxvd2VyQm91bmQpLi4uKQogICAgICAgICAgICByZXR1cm4gc3RyaXBwZWQKICAgICAgICB9KCkKICAgICAgICByZXR1cm5UeXBlU3RyaXBwZWQgPSByZXR1cm5UeXBlU3RyaXBwZWQudHJpbW1pbmdDaGFyYWN0ZXJzKGluOiBDaGFyYWN0ZXJTZXQoY2hhcmFjdGVyc0luOiAiICIpKQogICAgICAgIHJldHVybiAiXCh1bmlxdWVOYW1lKS0+XChyZXR1cm5UeXBlU3RyaXBwZWQpIgogICAgfQogICAgcHJpdmF0ZSB2YXIgbmFtZVN1ZmZpeDogU3RyaW5nIHsKICAgICAgICBndWFyZCBsZXQgY291bnQgPSBNZXRob2RXcmFwcGVyLnJlZ2lzdGVyZWRbcmVnaXN0cmF0aW9uTmFtZV0gZWxzZSB7IHJldHVybiAiIiB9CiAgICAgICAgZ3VhcmQgY291bnQgPiAxIGVsc2UgeyByZXR1cm4gIiIgfQogICAgICAgIGd1YXJkIGxldCBpbmRleCA9IE1ldGhvZFdyYXBwZXIuc3VmZml4ZXNbdW5pcXVlTmFtZVdpdGhSZXR1cm5UeXBlXSBlbHNlIHsgcmV0dXJuICIiIH0KICAgICAgICByZXR1cm4gIl9cKGluZGV4KSIKICAgIH0KICAgIHByaXZhdGUgdmFyIG1ldGhvZEF0dHJpYnV0ZXM6IFN0cmluZyB7CiAgICAgICAgcmV0dXJuIEhlbHBlcnMuZXh0cmFjdEF0dHJpYnV0ZXMoZnJvbTogc2VsZi5tZXRob2QuYXR0cmlidXRlcywgZmlsdGVyT3V0U3RhcnRpbmdXaXRoOiBbIm11dGF0aW5nIiwgIkBpbmxpbmFibGUiXSkKICAgIH0KICAgIHByaXZhdGUgdmFyIG1ldGhvZEF0dHJpYnV0ZXNOb25PYmpjOiBTdHJpbmcgewogICAgICAgIHJldHVybiBIZWxwZXJzLmV4dHJhY3RBdHRyaWJ1dGVzKGZyb206IHNlbGYubWV0aG9kLmF0dHJpYnV0ZXMsIGZpbHRlck91dFN0YXJ0aW5nV2l0aDogWyJtdXRhdGluZyIsICJAaW5saW5hYmxlIiwgIkBvYmpjIl0pCiAgICB9CgogICAgdmFyIHByb3RvdHlwZTogU3RyaW5nIHsKICAgICAgICByZXR1cm4gIlwocmVnaXN0cmF0aW9uTmFtZSlcKG5hbWVTdWZmaXgpIi5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogImAiLCB3aXRoOiAiIikKICAgIH0KICAgIHZhciBwYXJhbWV0ZXJzOiBbUGFyYW1ldGVyV3JhcHBlcl0gewogICAgICAgIHJldHVybiBmaWx0ZXJlZFBhcmFtZXRlcnMubWFwIHsgUGFyYW1ldGVyV3JhcHBlcigkMCwgc2VsZi5nZXRWYXJpYWRpY1BhcmFtZXRlcnNOYW1lcygpKSB9CiAgICB9CiAgICB2YXIgZmlsdGVyZWRQYXJhbWV0ZXJzOiBbTWV0aG9kUGFyYW1ldGVyXSB7CiAgICAgICAgcmV0dXJuIG1ldGhvZC5wYXJhbWV0ZXJzLmZpbHRlciB7ICQwLm5hbWUgIT0gIiIgfQogICAgfQogICAgdmFyIGZ1bmN0aW9uUHJvdG90eXBlOiBTdHJpbmcgewogICAgICAgIGxldCB0aHJvd2luZzogU3RyaW5nID0gewogICAgICAgICAgICBpZiBtZXRob2QudGhyb3dzIHsKICAgICAgICAgICAgICAgIHJldHVybiAidGhyb3dzICIKICAgICAgICAgICAgfSBlbHNlIGlmIG1ldGhvZC5yZXRocm93cyB7CiAgICAgICAgICAgICAgICByZXR1cm4gInJldGhyb3dzICIKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiAiIgogICAgICAgICAgICB9CiAgICAgICAgfSgpCgogICAgICAgIGxldCBzdGF0aWNNb2RpZmllcjogU3RyaW5nID0gIlwoYWNjZXNzTW9kaWZpZXIpICIKICAgICAgICBsZXQgcGFyYW1zID0gcmVwbGFjaW5nU2VsZihwYXJhbWV0ZXJzRm9yU3R1YlNpZ25hdHVyZSgpKQogICAgICAgIHZhciBhdHRyaWJ1dGVzID0gc2VsZi5tZXRob2RBdHRyaWJ1dGVzCiAgICAgICAgYXR0cmlidXRlcyA9IGF0dHJpYnV0ZXMuaXNFbXB0eSA/ICIiIDogIlwoYXR0cmlidXRlcylcblx0IgogICAgICAgIHZhciBhc3luY01vZGlmaWVyID0gc2VsZi5pc0FzeW5jID8gImFzeW5jICIgOiAiIgoKICAgICAgICBpZiBtZXRob2QuaXNJbml0aWFsaXplciB7CiAgICAgICAgICAgIHJldHVybiAiXChhdHRyaWJ1dGVzKXB1YmxpYyByZXF1aXJlZCBcKG1ldGhvZC5uYW1lKSBcKGFzeW5jTW9kaWZpZXIpXCh0aHJvd2luZykiCiAgICAgICAgfSBlbHNlIGlmIG1ldGhvZC5yZXR1cm5UeXBlTmFtZS5pc1ZvaWQgewogICAgICAgICAgICBsZXQgd2hlcmVQYXJ0SWZOZWVkZWQ6IFN0cmluZyA9IHsKICAgICAgICAgICAgICAgIGlmIG1ldGhvZC5yZXR1cm5UeXBlTmFtZS5uYW1lLmhhc1ByZWZpeCgiVm9pZCIpIHsKICAgICAgICAgICAgICAgICAgICBsZXQgcmFuZ2UgPSBtZXRob2QucmV0dXJuVHlwZU5hbWUubmFtZS5yYW5nZShvZjogIlZvaWQiKSEKICAgICAgICAgICAgICAgICAgICByZXR1cm4gIlwobWV0aG9kLnJldHVyblR5cGVOYW1lLm5hbWVbcmFuZ2UudXBwZXJCb3VuZC4uLl0pIgogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gIW1ldGhvZC5yZXR1cm5UeXBlTmFtZS5uYW1lLmlzRW1wdHkgPyAiXChtZXRob2QucmV0dXJuVHlwZU5hbWUubmFtZSkgIiA6ICIiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0oKQogICAgICAgICAgICByZXR1cm4gIlwoYXR0cmlidXRlcylcKHN0YXRpY01vZGlmaWVyKWZ1bmMgXChtZXRob2Quc2hvcnROYW1lKVwocGFyYW1zKSBcKGFzeW5jTW9kaWZpZXIpXCh0aHJvd2luZylcKHdoZXJlUGFydElmTmVlZGVkKSIKICAgICAgICB9IGVsc2UgaWYgcmV0dXJuc0dlbmVyaWNDb25zdHJhaW5lZFRvU2VsZiB7CiAgICAgICAgICAgIHJldHVybiAiXChhdHRyaWJ1dGVzKVwoc3RhdGljTW9kaWZpZXIpZnVuYyBcKG1ldGhvZC5zaG9ydE5hbWUpXChwYXJhbXMpIFwoYXN5bmNNb2RpZmllcilcKHRocm93aW5nKS0+IFwocmV0dXJuVHlwZVJlcGxhY2luZ1NlbGYpICIKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gIlwoYXR0cmlidXRlcylcKHN0YXRpY01vZGlmaWVyKWZ1bmMgXChtZXRob2Quc2hvcnROYW1lKVwocGFyYW1zKSBcKGFzeW5jTW9kaWZpZXIpXCh0aHJvd2luZyktPiBcKG1ldGhvZC5yZXR1cm5UeXBlTmFtZS5uYW1lKSAiCiAgICAgICAgfQogICAgfQogICAgdmFyIGludm9jYXRpb246IFN0cmluZyB7CiAgICAgICAgZ3VhcmQgIW1ldGhvZC5pc0luaXRpYWxpemVyIGVsc2UgeyByZXR1cm4gIiIgfQogICAgICAgIGlmIGZpbHRlcmVkUGFyYW1ldGVycy5pc0VtcHR5IHsKICAgICAgICAgICAgcmV0dXJuICJhZGRJbnZvY2F0aW9uKC5cKHByb3RvdHlwZSkpIgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAiYWRkSW52b2NhdGlvbiguXChwcm90b3R5cGUpKFwocGFyYW1ldGVyc0Zvck1ldGhvZENhbGwoKSkpKSIKICAgICAgICB9CiAgICB9CiAgICB2YXIgZ2l2ZW5WYWx1ZTogU3RyaW5nIHsKICAgICAgICBndWFyZCAhbWV0aG9kLmlzSW5pdGlhbGl6ZXIgZWxzZSB7IHJldHVybiAiIiB9CiAgICAgICAgZ3VhcmQgbWV0aG9kLnRocm93cyB8fCAhbWV0aG9kLnJldHVyblR5cGVOYW1lLmlzVm9pZCBlbHNlIHsgcmV0dXJuICIiIH0KCiAgICAgICAgbGV0IG1ldGhvZFR5cGUgPSBmaWx0ZXJlZFBhcmFtZXRlcnMuaXNFbXB0eSA/ICIuXChwcm90b3R5cGUpIiA6ICIuXChwcm90b3R5cGUpKFwocGFyYW1ldGVyc0Zvck1ldGhvZENhbGwoKSkpIgogICAgICAgIGxldCByZXR1cm5UeXBlOiBTdHJpbmcgPSByZXR1cm5zU2VsZiA/ICJfX1NlbGZfXyIgOiAiXChUeXBlV3JhcHBlcihtZXRob2QucmV0dXJuVHlwZU5hbWUpLnN0cmlwcGVkKSIKCiAgICAgICAgaWYgbWV0aG9kLnJldHVyblR5cGVOYW1lLmlzVm9pZCB7CiAgICAgICAgICAgIHJldHVybiAiIiIKICAgICAgICAgICAgXG5cdFx0ZG8gewogICAgICAgICAgICBcdFx0ICAgIF8gPSB0cnkgbWV0aG9kUmV0dXJuVmFsdWUoXChtZXRob2RUeXBlKSkuY2FzdGVkKCkgYXMgVm9pZAogICAgICAgICAgICBcdFx0fVwoIiAiKQogICAgICAgICAgICAiIiIKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBsZXQgZGVmYXVsdFZhbHVlID0gbWV0aG9kLnJldHVyblR5cGVOYW1lLmlzT3B0aW9uYWwgPyAiID0gbmlsIiA6ICIiCiAgICAgICAgICAgIHJldHVybiAiIiIKICAgICAgICAgICAgXG5cdFx0dmFyIF9fdmFsdWU6IFwocmV0dXJuVHlwZSlcKGRlZmF1bHRWYWx1ZSkKICAgICAgICAgICAgXHRcdGRvIHsKICAgICAgICAgICAgXHRcdCAgICBfX3ZhbHVlID0gdHJ5IG1ldGhvZFJldHVyblZhbHVlKFwobWV0aG9kVHlwZSkpLmNhc3RlZCgpCiAgICAgICAgICAgIFx0XHR9XCgiICIpCiAgICAgICAgICAgICIiIgogICAgICAgIH0KICAgIH0KICAgIHZhciB0aHJvd1ZhbHVlOiBTdHJpbmcgewogICAgICAgIGd1YXJkICFtZXRob2QuaXNJbml0aWFsaXplciBlbHNlIHsgcmV0dXJuICIiIH0KICAgICAgICBndWFyZCBtZXRob2QudGhyb3dzIHx8ICFtZXRob2QucmV0dXJuVHlwZU5hbWUuaXNWb2lkIGVsc2UgeyByZXR1cm4gIiIgfQogICAgICAgIGxldCBzYWZlRmFpbHVyZSA9IG1ldGhvZC5pc1N0YXRpYyA/ICIiIDogIlx0XHRcdG9uRmF0YWxGYWlsdXJlKFwiXChub1N0dWJEZWZpbmVkTWVzc2FnZSlcIilcbiIKICAgICAgICAvLyBGb3IgVm9pZCBhbmQgUmV0dXJuaW5nIG9wdGlvbmFscyAtIHdlIGFsbG93IG5vdCBzdHViYmVkIGNhc2UgdG8gaGFwcGVuLCBhcyB3ZSBhcmUgc3RpbGwgYWJsZSB0byByZXR1cm4KICAgICAgICBsZXQgbm9TdHViSGFuZGxpbmcgPSBtZXRob2QucmV0dXJuVHlwZU5hbWUuaXNWb2lkIHx8IG1ldGhvZC5yZXR1cm5UeXBlTmFtZS5pc09wdGlvbmFsID8gIlx0XHRcdC8vIGRvIG5vdGhpbmciIDogIlwoc2FmZUZhaWx1cmUpXHRcdFx0RmFpbHVyZShcIlwobm9TdHViRGVmaW5lZE1lc3NhZ2UpXCIpIgogICAgICAgIGd1YXJkIG1ldGhvZC50aHJvd3MgZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAiIiIKICAgICAgICAgICAgY2F0Y2ggewogICAgICAgICAgICBcKG5vU3R1YkhhbmRsaW5nKQogICAgICAgICAgICBcdFx0fQogICAgICAgICAgICAiIiIKICAgICAgICB9CgogICAgICAgIHJldHVybiAiIiIKICAgICAgICBjYXRjaCBNb2NrRXJyb3Iubm90U3R1YmVkIHsKICAgICAgICBcKG5vU3R1YkhhbmRsaW5nKQogICAgICAgIFx0XHR9IGNhdGNoIHsKICAgICAgICBcdFx0ICAgIHRocm93IGVycm9yCiAgICAgICAgXHRcdH0KICAgICAgICAiIiIKICAgIH0KICAgIHZhciByZXR1cm5WYWx1ZTogU3RyaW5nIHsKICAgICAgICBndWFyZCAhbWV0aG9kLmlzSW5pdGlhbGl6ZXIgZWxzZSB7IHJldHVybiAiIiB9CiAgICAgICAgZ3VhcmQgIW1ldGhvZC5yZXR1cm5UeXBlTmFtZS5pc1ZvaWQgZWxzZSB7IHJldHVybiAiIiB9CgogICAgICAgIHJldHVybiAiXG5cdFx0cmV0dXJuIF9fdmFsdWUiCiAgICB9CiAgICB2YXIgZXF1YWxDYXNlOiBTdHJpbmcgewogICAgICAgIGd1YXJkICFtZXRob2QuaXNJbml0aWFsaXplciBlbHNlIHsgcmV0dXJuICIiIH0KCiAgICAgICAgaWYgZmlsdGVyZWRQYXJhbWV0ZXJzLmlzRW1wdHkgewogICAgICAgICAgICByZXR1cm4gImNhc2UgKC5cKHByb3RvdHlwZSksIC5cKHByb3RvdHlwZSkpOiIKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBsZXQgbGhzUGFyYW1zID0gZmlsdGVyZWRQYXJhbWV0ZXJzLm1hcCB7ICJsZXQgbGhzXCgkMC5uYW1lLmNhcGl0YWxpemVkKSIgfS5qb2luZWQoc2VwYXJhdG9yOiAiLCAiKQogICAgICAgICAgICBsZXQgcmhzUGFyYW1zID0gZmlsdGVyZWRQYXJhbWV0ZXJzLm1hcCB7ICJsZXQgcmhzXCgkMC5uYW1lLmNhcGl0YWxpemVkKSIgfS5qb2luZWQoc2VwYXJhdG9yOiAiLCAiKQogICAgICAgICAgICByZXR1cm4gImNhc2UgKC5cKHByb3RvdHlwZSkoXChsaHNQYXJhbXMpKSwgLlwocHJvdG90eXBlKShcKHJoc1BhcmFtcykpKToiCiAgICAgICAgfQogICAgfQogICAgZnVuYyBlcXVhbENhc2VzKCkgLT4gU3RyaW5nIHsKICAgICAgICB2YXIgcmVzdWx0cyA9IHNlbGYuZXF1YWxDYXNlCgogICAgICAgIGd1YXJkICFwYXJhbWV0ZXJzLmlzRW1wdHkgZWxzZSB7CiAgICAgICAgICAgIHJlc3VsdHMgKz0gIiByZXR1cm4gLm1hdGNoIgogICAgICAgICAgICByZXR1cm4gcmVzdWx0cwogICAgICAgIH0KCiAgICAgICAgcmVzdWx0cyArPSAiXG5cdFx0XHRcdHZhciByZXN1bHRzOiBbTWF0Y2hlci5QYXJhbWV0ZXJDb21wYXJpc29uUmVzdWx0XSA9IFtdXG4iCiAgICAgICAgcmVzdWx0cyArPSBwYXJhbWV0ZXJzLm1hcCB7ICJcdFx0XHRcdFwoJDAuY29tcGFyYXRvclJlc3VsdCgpKSIgfS5qb2luZWQoc2VwYXJhdG9yOiAiXG4iKQogICAgICAgIHJlc3VsdHMgKz0gIlxuXHRcdFx0XHRyZXR1cm4gTWF0Y2hlci5Db21wYXJpc29uUmVzdWx0KHJlc3VsdHMpIgogICAgICAgIHJldHVybiByZXN1bHRzCiAgICB9CiAgICB2YXIgaW50VmFsdWVDYXNlOiBTdHJpbmcgewogICAgICAgIGlmIGZpbHRlcmVkUGFyYW1ldGVycy5pc0VtcHR5IHsKICAgICAgICAgICAgcmV0dXJuICJjYXNlIC5cKHByb3RvdHlwZSk6IHJldHVybiAwIgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGxldCBwYXJhbXMgPSBmaWx0ZXJlZFBhcmFtZXRlcnMuZW51bWVyYXRlZCgpLm1hcCB7IG9mZnNldCwgXyBpbgogICAgICAgICAgICAgICAgcmV0dXJuICJwXChvZmZzZXQpIgogICAgICAgICAgICB9CiAgICAgICAgICAgIGxldCBkZWZpbml0aW9ucyA9IHBhcmFtcy5qb2luZWQoc2VwYXJhdG9yOiAiLCAiKQogICAgICAgICAgICBsZXQgcGFyYW1zU3VtID0gcGFyYW1zLm1hcCh7ICJcKCQwKS5pbnRWYWx1ZSIgfSkuam9pbmVkKHNlcGFyYXRvcjogIiArICIpCiAgICAgICAgICAgIHJldHVybiAiY2FzZSBsZXQgLlwocHJvdG90eXBlKShcKGRlZmluaXRpb25zKSk6IHJldHVybiBcKHBhcmFtc1N1bSkiCiAgICAgICAgfQogICAgfQogICAgdmFyIGFzc2VydGlvbk5hbWU6IFN0cmluZyB7CiAgICAgICAgcmV0dXJuICJjYXNlIC5cKHByb3RvdHlwZSk6IHJldHVybiBcIi5cKG1ldGhvZC5zZWxlY3Rvck5hbWUpXChtZXRob2QucGFyYW1ldGVycy5pc0VtcHR5ID8gIigpIiA6ICIiKVwiIgogICAgfQoKICAgIHZhciByZXR1cm5zU2VsZjogQm9vbCB7CiAgICAgICAgZ3VhcmQgIXJldHVybnNHZW5lcmljQ29uc3RyYWluZWRUb1NlbGYgZWxzZSB7IHJldHVybiB0cnVlIH0KICAgICAgICByZXR1cm4gIW1ldGhvZC5yZXR1cm5UeXBlTmFtZS5pc1ZvaWQgJiYgVHlwZVdyYXBwZXIobWV0aG9kLnJldHVyblR5cGVOYW1lKS5pc1NlbGZUeXBlCiAgICB9CiAgICB2YXIgcmV0dXJuc0dlbmVyaWNDb25zdHJhaW5lZFRvU2VsZjogQm9vbCB7CiAgICAgICAgbGV0IGRlZmF1bHRSZXR1cm5UeXBlID0gIlwobWV0aG9kLnJldHVyblR5cGVOYW1lLm5hbWUpICIKICAgICAgICByZXR1cm4gZGVmYXVsdFJldHVyblR5cGUgIT0gcmV0dXJuVHlwZVJlcGxhY2luZ1NlbGYKICAgIH0KICAgIHZhciByZXR1cm5UeXBlUmVwbGFjaW5nU2VsZjogU3RyaW5nIHsKICAgICAgICByZXR1cm4gcmVwbGFjaW5nU2VsZigiXChtZXRob2QucmV0dXJuVHlwZU5hbWUubmFtZSkgIikKICAgIH0KICAgIHZhciBwYXJhbWV0ZXJzQ29udGFpbnNTZWxmOiBCb29sIHsKICAgICAgICByZXR1cm4gcmVwbGFjaW5nU2VsZihwYXJhbWV0ZXJzRm9yU3R1YlNpZ25hdHVyZSgpKSAhPSBwYXJhbWV0ZXJzRm9yU3R1YlNpZ25hdHVyZSgpCiAgICB9CgogICAgdmFyIHJlcGxhY2VTZWxmOiBTdHJpbmcgewogICAgICAgIHJldHVybiBDdXJyZW50LnNlbGZUeXBlCiAgICB9CgogICAgaW5pdChfIG1ldGhvZDogU291cmNlcnlSdW50aW1lLk1ldGhvZCkgewogICAgICAgIHNlbGYubWV0aG9kID0gbWV0aG9kCiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmdW5jIGNsZWFyKCkgLT4gU3RyaW5nIHsKICAgICAgICBNZXRob2RXcmFwcGVyLnJlZ2lzdGVyZWQgPSBbOl0KICAgICAgICBNZXRob2RXcmFwcGVyLnN1ZmZpeGVzID0gWzpdCiAgICAgICAgTWV0aG9kV3JhcHBlci5zdWZmaXhlc1dpdGhvdXRSZXR1cm5UeXBlID0gWzpdCiAgICAgICAgcmV0dXJuICIiCiAgICB9CgogICAgZnVuYyByZWdpc3RlcigpIHsKICAgICAgICBNZXRob2RXcmFwcGVyLnJlZ2lzdGVyKHJlZ2lzdHJhdGlvbk5hbWUsdW5pcXVlTmFtZSx1bmlxdWVOYW1lV2l0aFJldHVyblR5cGUpCiAgICB9CgogICAgc3RhdGljIGZ1bmMgcmVnaXN0ZXIoXyBuYW1lOiBTdHJpbmcsIF8gdW5pcXVlTmFtZTogU3RyaW5nLCBfIHVuaXF1ZU5hbWVXaXRoUmV0dXJuVHlwZTogU3RyaW5nKSB7CiAgICAgICAgaWYgbGV0IGNvdW50ID0gTWV0aG9kV3JhcHBlci5yZWdpc3RlcmVkW25hbWVdIHsKICAgICAgICAgICAgTWV0aG9kV3JhcHBlci5yZWdpc3RlcmVkW25hbWVdID0gY291bnQgKyAxCiAgICAgICAgICAgIE1ldGhvZFdyYXBwZXIuc3VmZml4ZXNbdW5pcXVlTmFtZVdpdGhSZXR1cm5UeXBlXSA9IGNvdW50ICsgMQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIE1ldGhvZFdyYXBwZXIucmVnaXN0ZXJlZFtuYW1lXSA9IDEKICAgICAgICAgICAgTWV0aG9kV3JhcHBlci5zdWZmaXhlc1t1bmlxdWVOYW1lV2l0aFJldHVyblR5cGVdID0gMQogICAgICAgIH0KCiAgICAgICAgaWYgbGV0IGNvdW50ID0gTWV0aG9kV3JhcHBlci5zdWZmaXhlc1dpdGhvdXRSZXR1cm5UeXBlW3VuaXF1ZU5hbWVdIHsKICAgICAgICAgICAgTWV0aG9kV3JhcHBlci5zdWZmaXhlc1dpdGhvdXRSZXR1cm5UeXBlW3VuaXF1ZU5hbWVdID0gY291bnQgKyAxCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgTWV0aG9kV3JhcHBlci5zdWZmaXhlc1dpdGhvdXRSZXR1cm5UeXBlW3VuaXF1ZU5hbWVdID0gMQogICAgICAgIH0KICAgIH0KCiAgICBmdW5jIHJldHVyblR5cGVNYXR0ZXJzKCkgLT4gQm9vbCB7CiAgICAgICAgbGV0IGNvdW50ID0gTWV0aG9kV3JhcHBlci5zdWZmaXhlc1dpdGhvdXRSZXR1cm5UeXBlW3VuaXF1ZU5hbWVdID8/IDAKICAgICAgICByZXR1cm4gY291bnQgPiAxCiAgICB9CgogICAgZnVuYyB3cmFwcGVkSW5NZXRob2RUeXBlKCkgLT4gQm9vbCB7CiAgICAgICAgcmV0dXJuICFtZXRob2QuaXNJbml0aWFsaXplcgogICAgfQoKICAgIGZ1bmMgcmV0dXJuaW5nUGFyYW1ldGVyKF8gbXVsdGlwbGU6IEJvb2wsIF8gZnJvbnQ6IEJvb2wpIC0+IFN0cmluZyB7CiAgICAgICAgZ3VhcmQgcmV0dXJuVHlwZU1hdHRlcnMoKSBlbHNlIHsgcmV0dXJuICIiIH0KICAgICAgICBsZXQgcmV0dXJuaW5nOiBTdHJpbmcgPSAicmV0dXJuaW5nOiBcKHJldHVyblR5cGVTdHJpcHBlZChtZXRob2QsIHR5cGU6IHRydWUpKSIKICAgICAgICBndWFyZCBtdWx0aXBsZSBlbHNlIHsgcmV0dXJuIHJldHVybmluZyB9CgogICAgICAgIHJldHVybiBmcm9udCA/ICIsIFwocmV0dXJuaW5nKSIgOiAiXChyZXR1cm5pbmcpLCAiCiAgICB9CgogICAgLy8gU3R1YgogICAgZnVuYyBzdHViQm9keSgpIC0+IFN0cmluZyB7CiAgICAgICAgbGV0IGJvZHk6IFN0cmluZyA9IHsKICAgICAgICAgICAgaWYgbWV0aG9kLmlzSW5pdGlhbGl6ZXIgfHwgIXJldHVybnNTZWxmIHsKICAgICAgICAgICAgICAgIHJldHVybiBpbnZvY2F0aW9uICsgcGVyZm9ybUNhbGwoKSArIGdpdmVuVmFsdWUgKyB0aHJvd1ZhbHVlICsgcmV0dXJuVmFsdWUKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiB3cmFwcGVkU3R1YlByZWZpeCgpCiAgICAgICAgICAgICAgICAgICAgKyAiXHRcdCIgKyBpbnZvY2F0aW9uCiAgICAgICAgICAgICAgICAgICAgKyBwZXJmb3JtQ2FsbCgpCiAgICAgICAgICAgICAgICAgICAgKyBnaXZlblZhbHVlCiAgICAgICAgICAgICAgICAgICAgKyB0aHJvd1ZhbHVlCiAgICAgICAgICAgICAgICAgICAgKyByZXR1cm5WYWx1ZQogICAgICAgICAgICAgICAgICAgICsgd3JhcHBlZFN0dWJQb3N0Zml4KCkKICAgICAgICAgICAgfQogICAgICAgIH0oKQogICAgICAgIHJldHVybiByZXBsYWNpbmdTZWxmKGJvZHkpCiAgICB9CgogICAgZnVuYyB3cmFwcGVkU3R1YlByZWZpeCgpIC0+IFN0cmluZyB7CiAgICAgICAgZ3VhcmQgIW1ldGhvZC5pc0luaXRpYWxpemVyLCByZXR1cm5zU2VsZiBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuICIiCiAgICAgICAgfQoKICAgICAgICBsZXQgdGhyb3dpbmc6IFN0cmluZyA9IHsKICAgICAgICAgICAgaWYgbWV0aG9kLnRocm93cyB7CiAgICAgICAgICAgICAgICByZXR1cm4gInRocm93cyAiCiAgICAgICAgICAgIH0gZWxzZSBpZiBtZXRob2QucmV0aHJvd3MgewogICAgICAgICAgICAgICAgcmV0dXJuICJyZXRocm93cyAiCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gIiIKICAgICAgICAgICAgfQogICAgICAgIH0oKQoKICAgICAgICByZXR1cm4gImZ1bmMgX3dyYXBwZWQ8X19TZWxmX18+KCkgXCh0aHJvd2luZyktPiBfX1NlbGZfXyB7XG4iCiAgICB9CgogICAgZnVuYyB3cmFwcGVkU3R1YlBvc3RmaXgoKSAtPiBTdHJpbmcgewogICAgICAgIGd1YXJkICFtZXRob2QuaXNJbml0aWFsaXplciwgcmV0dXJuc1NlbGYgZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAiIgogICAgICAgIH0KCiAgICAgICAgbGV0IHRocm93aW5nOiBTdHJpbmcgPSAobWV0aG9kLnRocm93cyB8fCBtZXRob2QucmV0aHJvd3MpID8gInRyeSAiOiAiIgoKICAgICAgICByZXR1cm4gIlxuXHRcdH0iCiAgICAgICAgICAgICsgIlxuXHRcdHJldHVybiBcKHRocm93aW5nKV93cmFwcGVkKCkiCiAgICB9CgogICAgLy8gTWV0aG9kIFR5cGUKICAgIGZ1bmMgbWV0aG9kVHlwZURlY2xhcmF0aW9uV2l0aFBhcmFtZXRlcnMoKSAtPiBTdHJpbmcgewogICAgICAgIGlmIGZpbHRlcmVkUGFyYW1ldGVycy5pc0VtcHR5IHsKICAgICAgICAgICAgcmV0dXJuICJjYXNlIFwocHJvdG90eXBlKSIKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gImNhc2UgXChwcm90b3R5cGUpKFwocGFyYW1ldGVyc0Zvck1ldGhvZFR5cGVEZWNsYXJhdGlvbihhdmFpbGFiaWxpdHk6IGhhc0F2YWlsYWJpbGl0eSkpKSIKICAgICAgICB9CiAgICB9CgogICAgLy8gR2l2ZW4KICAgIGZ1bmMgY29udGFpbnNFbXB0eUFyZ3VtZW50TGFiZWxzKCkgLT4gQm9vbCB7CiAgICAgICAgcmV0dXJuIHBhcmFtZXRlcnMuY29udGFpbnMod2hlcmU6IHsgJDAucGFyYW1ldGVyLmFyZ3VtZW50TGFiZWwgPT0gbmlsIH0pCiAgICB9CgogICAgZnVuYyBnaXZlblJldHVyblR5cGVTdHJpbmcoKSAtPiBTdHJpbmcgewogICAgICAgIGxldCByZXR1cm5UeXBlU3RyaW5nOiBTdHJpbmcgPSB7CiAgICAgICAgICAgIGd1YXJkICFyZXR1cm5zR2VuZXJpY0NvbnN0cmFpbmVkVG9TZWxmIGVsc2UgeyByZXR1cm4gcmV0dXJuVHlwZVJlcGxhY2luZ1NlbGYgfQogICAgICAgICAgICBndWFyZCAhcmV0dXJuc1NlbGYgZWxzZSB7IHJldHVybiByZXBsYWNlU2VsZiB9CiAgICAgICAgICAgIHJldHVybiBUeXBlV3JhcHBlcihtZXRob2QucmV0dXJuVHlwZU5hbWUpLnN0cmlwcGVkCiAgICAgICAgfSgpCiAgICAgICAgcmV0dXJuIHJldHVyblR5cGVTdHJpbmcKICAgIH0KCiAgICBmdW5jIGdpdmVuQ29uc3RydWN0b3JOYW1lKHByZWZpeDogU3RyaW5nID0gIiIpIC0+IFN0cmluZyB7CiAgICAgICAgbGV0IHJldHVyblR5cGVTdHJpbmcgPSBnaXZlblJldHVyblR5cGVTdHJpbmcoKQogICAgICAgIGxldCAoYW5ub3RhdGlvbiwgXywgXykgPSBtZXRob2RJbmZvKCkKICAgICAgICBsZXQgY2xhdXNlQ29uc3RyYWludHMgPSB3aGVyZUNsYXVzZUV4cHJlc3Npb24oKQoKICAgICAgICBpZiBmaWx0ZXJlZFBhcmFtZXRlcnMuaXNFbXB0eSB7CiAgICAgICAgICAgIHJldHVybiAiXChhbm5vdGF0aW9uKXB1YmxpYyBzdGF0aWMgZnVuYyBcKG1ldGhvZC5zaG9ydE5hbWUpKHdpbGxSZXR1cm46IFwocmV0dXJuVHlwZVN0cmluZykuLi4pIC0+IFwocHJlZml4KU1ldGhvZFN0dWIiICsgY2xhdXNlQ29uc3RyYWludHMKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gIlwoYW5ub3RhdGlvbilwdWJsaWMgc3RhdGljIGZ1bmMgXChtZXRob2Quc2hvcnROYW1lKShcKHBhcmFtZXRlcnNGb3JQcm94eVNpZ25hdHVyZSgpKSwgd2lsbFJldHVybjogXChyZXR1cm5UeXBlU3RyaW5nKS4uLikgLT4gXChwcmVmaXgpTWV0aG9kU3R1YiIgKyBjbGF1c2VDb25zdHJhaW50cwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jIGdpdmVuQ29uc3RydWN0b3JOYW1lVGhyb3dzKHByZWZpeDogU3RyaW5nID0gIiIpIC0+IFN0cmluZyB7CiAgICAgICAgbGV0IChhbm5vdGF0aW9uLCBfLCBfKSA9IG1ldGhvZEluZm8oKQogICAgICAgIGxldCBjbGF1c2VDb25zdHJhaW50cyA9IHdoZXJlQ2xhdXNlRXhwcmVzc2lvbigpCgogICAgICAgIGxldCBnZW5lcmljc0FycmF5ID0gZ2V0R2VuZXJpY3NDb25zdHJhaW50cyhnZXRHZW5lcmljc0Ftb25nUGFyYW1ldGVycygpLCBmaWx0ZXJTaW5nbGU6IGZhbHNlKQogICAgICAgIGxldCBnZW5lcmljcyA9IGdlbmVyaWNzQXJyYXkuaXNFbXB0eSA/ICIiIDogIjxcKGdlbmVyaWNzQXJyYXkuam9pbmVkKHNlcGFyYXRvcjogIiwgIikpPiIKCiAgICAgICAgaWYgZmlsdGVyZWRQYXJhbWV0ZXJzLmlzRW1wdHkgewogICAgICAgICAgICByZXR1cm4gIlwoYW5ub3RhdGlvbilwdWJsaWMgc3RhdGljIGZ1bmMgXChtZXRob2QuY2FsbE5hbWUpXChnZW5lcmljcykod2lsbFRocm93OiBFcnJvci4uLikgLT4gXChwcmVmaXgpTWV0aG9kU3R1YiIgKyBjbGF1c2VDb25zdHJhaW50cwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAiXChhbm5vdGF0aW9uKXB1YmxpYyBzdGF0aWMgZnVuYyBcKG1ldGhvZC5jYWxsTmFtZSlcKGdlbmVyaWNzKShcKHBhcmFtZXRlcnNGb3JQcm94eVNpZ25hdHVyZSgpKSwgd2lsbFRocm93OiBFcnJvci4uLikgLT4gXChwcmVmaXgpTWV0aG9kU3R1YiIgKyBjbGF1c2VDb25zdHJhaW50cwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jIGdpdmVuQ29uc3RydWN0b3IocHJlZml4OiBTdHJpbmcgPSAiIikgLT4gU3RyaW5nIHsKICAgICAgICBpZiBmaWx0ZXJlZFBhcmFtZXRlcnMuaXNFbXB0eSB7CiAgICAgICAgICAgIHJldHVybiAicmV0dXJuIFwocHJlZml4KUdpdmVuKG1ldGhvZDogLlwocHJvdG90eXBlKSwgcHJvZHVjdHM6IHdpbGxSZXR1cm4ubWFwKHsgU3R1YlByb2R1Y3QucmV0dXJuKCQwIGFzIEFueSkgfSkpIgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAicmV0dXJuIFwocHJlZml4KUdpdmVuKG1ldGhvZDogLlwocHJvdG90eXBlKShcKHBhcmFtZXRlcnNGb3JQcm94eUluaXQoKSkpLCBwcm9kdWN0czogd2lsbFJldHVybi5tYXAoeyBTdHViUHJvZHVjdC5yZXR1cm4oJDAgYXMgQW55KSB9KSkiCiAgICAgICAgfQogICAgfQoKICAgIGZ1bmMgZ2l2ZW5Db25zdHJ1Y3RvclRocm93cyhwcmVmaXg6IFN0cmluZyA9ICIiKSAtPiBTdHJpbmcgewogICAgICAgIGlmIGZpbHRlcmVkUGFyYW1ldGVycy5pc0VtcHR5IHsKICAgICAgICAgICAgcmV0dXJuICJyZXR1cm4gXChwcmVmaXgpR2l2ZW4obWV0aG9kOiAuXChwcm90b3R5cGUpLCBwcm9kdWN0czogd2lsbFRocm93Lm1hcCh7IFN0dWJQcm9kdWN0LnRocm93KCQwKSB9KSkiCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuICJyZXR1cm4gXChwcmVmaXgpR2l2ZW4obWV0aG9kOiAuXChwcm90b3R5cGUpKFwocGFyYW1ldGVyc0ZvclByb3h5SW5pdCgpKSksIHByb2R1Y3RzOiB3aWxsVGhyb3cubWFwKHsgU3R1YlByb2R1Y3QudGhyb3coJDApIH0pKSIKICAgICAgICB9CiAgICB9CgogICAgLy8gR2l2ZW4gd2lsbFByb2R1Y2UKICAgIGZ1bmMgZ2l2ZW5Qcm9kdWNlQ29uc3RydWN0b3JOYW1lKHByZWZpeDogU3RyaW5nID0gIiIpIC0+IFN0cmluZyB7CiAgICAgICAgbGV0IHJldHVyblR5cGVTdHJpbmcgPSBnaXZlblJldHVyblR5cGVTdHJpbmcoKQogICAgICAgIGxldCAoYW5ub3RhdGlvbiwgXywgXykgPSBtZXRob2RJbmZvKCkKICAgICAgICBsZXQgcHJvZHVjZUNsb3N1cmUgPSAiKFN0dWJiZXI8XChyZXR1cm5UeXBlU3RyaW5nKT4pIC0+IFZvaWQiCiAgICAgICAgbGV0IGNsYXVzZUNvbnN0cmFpbnRzID0gd2hlcmVDbGF1c2VFeHByZXNzaW9uKCkKCiAgICAgICAgaWYgZmlsdGVyZWRQYXJhbWV0ZXJzLmlzRW1wdHkgewogICAgICAgICAgICByZXR1cm4gIlwoYW5ub3RhdGlvbilwdWJsaWMgc3RhdGljIGZ1bmMgXChtZXRob2Quc2hvcnROYW1lKSh3aWxsUHJvZHVjZTogXChwcm9kdWNlQ2xvc3VyZSkpIC0+IFwocHJlZml4KU1ldGhvZFN0dWIiICsgY2xhdXNlQ29uc3RyYWludHMKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gIlwoYW5ub3RhdGlvbilwdWJsaWMgc3RhdGljIGZ1bmMgXChtZXRob2Quc2hvcnROYW1lKShcKHBhcmFtZXRlcnNGb3JQcm94eVNpZ25hdHVyZSgpKSwgd2lsbFByb2R1Y2U6IFwocHJvZHVjZUNsb3N1cmUpKSAtPiBcKHByZWZpeClNZXRob2RTdHViIiArIGNsYXVzZUNvbnN0cmFpbnRzCiAgICAgICAgfQogICAgfQoKICAgIGZ1bmMgZ2l2ZW5Qcm9kdWNlQ29uc3RydWN0b3JOYW1lVGhyb3dzKHByZWZpeDogU3RyaW5nID0gIiIpIC0+IFN0cmluZyB7CiAgICAgICAgbGV0IHJldHVyblR5cGVTdHJpbmcgPSBnaXZlblJldHVyblR5cGVTdHJpbmcoKQogICAgICAgIGxldCAoYW5ub3RhdGlvbiwgXywgXykgPSBtZXRob2RJbmZvKCkKICAgICAgICBsZXQgcHJvZHVjZUNsb3N1cmUgPSAiKFN0dWJiZXJUaHJvd3M8XChyZXR1cm5UeXBlU3RyaW5nKT4pIC0+IFZvaWQiCiAgICAgICAgbGV0IGNsYXVzZUNvbnN0cmFpbnRzID0gd2hlcmVDbGF1c2VFeHByZXNzaW9uKCkKCiAgICAgICAgaWYgZmlsdGVyZWRQYXJhbWV0ZXJzLmlzRW1wdHkgewogICAgICAgICAgICByZXR1cm4gIlwoYW5ub3RhdGlvbilwdWJsaWMgc3RhdGljIGZ1bmMgXChtZXRob2Quc2hvcnROYW1lKSh3aWxsUHJvZHVjZTogXChwcm9kdWNlQ2xvc3VyZSkpIC0+IFwocHJlZml4KU1ldGhvZFN0dWIiICsgY2xhdXNlQ29uc3RyYWludHMKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gIlwoYW5ub3RhdGlvbilwdWJsaWMgc3RhdGljIGZ1bmMgXChtZXRob2Quc2hvcnROYW1lKShcKHBhcmFtZXRlcnNGb3JQcm94eVNpZ25hdHVyZSgpKSwgd2lsbFByb2R1Y2U6IFwocHJvZHVjZUNsb3N1cmUpKSAtPiBcKHByZWZpeClNZXRob2RTdHViIiArIGNsYXVzZUNvbnN0cmFpbnRzCiAgICAgICAgfQogICAgfQoKICAgIGZ1bmMgZ2l2ZW5Qcm9kdWNlQ29uc3RydWN0b3IocHJlZml4OiBTdHJpbmcgPSAiIikgLT4gU3RyaW5nIHsKICAgICAgICBsZXQgcmV0dXJuVHlwZVN0cmluZyA9IGdpdmVuUmV0dXJuVHlwZVN0cmluZygpCiAgICAgICAgcmV0dXJuICIiIgogICAgICAgIGxldCB3aWxsUmV0dXJuOiBbXChyZXR1cm5UeXBlU3RyaW5nKV0gPSBbXQogICAgICAgIFx0XHRcdGxldCBnaXZlbjogXChwcmVmaXgpR2l2ZW4gPSB7IFwoZ2l2ZW5Db25zdHJ1Y3RvcihwcmVmaXg6IHByZWZpeCkpIH0oKQogICAgICAgIFx0XHRcdGxldCBzdHViYmVyID0gZ2l2ZW4uc3R1Yihmb3I6IChcKHJldHVyblR5cGVTdHJpbmcpKS5zZWxmKQogICAgICAgIFx0XHRcdHdpbGxQcm9kdWNlKHN0dWJiZXIpCiAgICAgICAgXHRcdFx0cmV0dXJuIGdpdmVuCiAgICAgICAgIiIiCiAgICB9CgogICAgZnVuYyBnaXZlblByb2R1Y2VDb25zdHJ1Y3RvclRocm93cyhwcmVmaXg6IFN0cmluZyA9ICIiKSAtPiBTdHJpbmcgewogICAgICAgIGxldCByZXR1cm5UeXBlU3RyaW5nID0gZ2l2ZW5SZXR1cm5UeXBlU3RyaW5nKCkKICAgICAgICByZXR1cm4gIiIiCiAgICAgICAgbGV0IHdpbGxUaHJvdzogW0Vycm9yXSA9IFtdCiAgICAgICAgXHRcdFx0bGV0IGdpdmVuOiBcKHByZWZpeClHaXZlbiA9IHsgXChnaXZlbkNvbnN0cnVjdG9yVGhyb3dzKHByZWZpeDogcHJlZml4KSkgfSgpCiAgICAgICAgXHRcdFx0bGV0IHN0dWJiZXIgPSBnaXZlbi5zdHViVGhyb3dzKGZvcjogKFwocmV0dXJuVHlwZVN0cmluZykpLnNlbGYpCiAgICAgICAgXHRcdFx0d2lsbFByb2R1Y2Uoc3R1YmJlcikKICAgICAgICBcdFx0XHRyZXR1cm4gZ2l2ZW4KICAgICAgICAiIiIKICAgIH0KCiAgICAvLyBWZXJpZnkKICAgIGZ1bmMgdmVyaWZpY2F0aW9uUHJveHlDb25zdHJ1Y3Rvck5hbWUocHJlZml4OiBTdHJpbmcgPSAiIikgLT4gU3RyaW5nIHsKICAgICAgICBsZXQgKGFubm90YXRpb24sIG1ldGhvZE5hbWUsIGdlbmVyaWNDb25zdHJhaW5zKSA9IG1ldGhvZEluZm8oKQoKICAgICAgICBpZiBmaWx0ZXJlZFBhcmFtZXRlcnMuaXNFbXB0eSB7CiAgICAgICAgICAgIHJldHVybiAiXChhbm5vdGF0aW9uKXB1YmxpYyBzdGF0aWMgZnVuYyBcKG1ldGhvZE5hbWUpKFwocmV0dXJuaW5nUGFyYW1ldGVyKGZhbHNlLHRydWUpKSkgLT4gXChwcmVmaXgpVmVyaWZ5XChnZW5lcmljQ29uc3RyYWlucykiCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuICJcKGFubm90YXRpb24pcHVibGljIHN0YXRpYyBmdW5jIFwobWV0aG9kTmFtZSkoXChwYXJhbWV0ZXJzRm9yUHJveHlTaWduYXR1cmUoKSlcKHJldHVybmluZ1BhcmFtZXRlcih0cnVlLHRydWUpKSkgLT4gXChwcmVmaXgpVmVyaWZ5XChnZW5lcmljQ29uc3RyYWlucykiCiAgICAgICAgfQogICAgfQoKICAgIGZ1bmMgdmVyaWZpY2F0aW9uUHJveHlDb25zdHJ1Y3RvcihwcmVmaXg6IFN0cmluZyA9ICIiKSAtPiBTdHJpbmcgewogICAgICAgIGlmIGZpbHRlcmVkUGFyYW1ldGVycy5pc0VtcHR5IHsKICAgICAgICAgICAgcmV0dXJuICJyZXR1cm4gXChwcmVmaXgpVmVyaWZ5KG1ldGhvZDogLlwocHJvdG90eXBlKSkiCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuICJyZXR1cm4gXChwcmVmaXgpVmVyaWZ5KG1ldGhvZDogLlwocHJvdG90eXBlKShcKHBhcmFtZXRlcnNGb3JQcm94eUluaXQoKSkpKSIKICAgICAgICB9CiAgICB9CgogICAgLy8gUGVyZm9ybQogICAgZnVuYyBwZXJmb3JtUHJveHlDb25zdHJ1Y3Rvck5hbWUocHJlZml4OiBTdHJpbmcgPSAiIikgLT4gU3RyaW5nIHsKICAgICAgICBsZXQgYm9keTogU3RyaW5nID0gewogICAgICAgICAgICBsZXQgKGFubm90YXRpb24sIG1ldGhvZE5hbWUsIGdlbmVyaWNDb25zdHJhaW5zKSA9IG1ldGhvZEluZm8oKQoKICAgICAgICAgICAgaWYgZmlsdGVyZWRQYXJhbWV0ZXJzLmlzRW1wdHkgewogICAgICAgICAgICAgICAgcmV0dXJuICJcKGFubm90YXRpb24pcHVibGljIHN0YXRpYyBmdW5jIFwobWV0aG9kTmFtZSkoXChyZXR1cm5pbmdQYXJhbWV0ZXIodHJ1ZSxmYWxzZSkpcGVyZm9ybTogQGVzY2FwaW5nIFwocGVyZm9ybVByb3h5Q2xvc3VyZVR5cGUoKSkpIC0+IFwocHJlZml4KVBlcmZvcm1cKGdlbmVyaWNDb25zdHJhaW5zKSIKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiAiXChhbm5vdGF0aW9uKXB1YmxpYyBzdGF0aWMgZnVuYyBcKG1ldGhvZE5hbWUpKFwocGFyYW1ldGVyc0ZvclByb3h5U2lnbmF0dXJlKCkpLCBcKHJldHVybmluZ1BhcmFtZXRlcih0cnVlLGZhbHNlKSlwZXJmb3JtOiBAZXNjYXBpbmcgXChwZXJmb3JtUHJveHlDbG9zdXJlVHlwZSgpKSkgLT4gXChwcmVmaXgpUGVyZm9ybVwoZ2VuZXJpY0NvbnN0cmFpbnMpIgogICAgICAgICAgICB9CiAgICAgICAgfSgpCiAgICAgICAgcmV0dXJuIHJlcGxhY2luZ1NlbGYoYm9keSkKICAgIH0KCiAgICBmdW5jIHBlcmZvcm1Qcm94eUNvbnN0cnVjdG9yKHByZWZpeDogU3RyaW5nID0gIiIpIC0+IFN0cmluZyB7CiAgICAgICAgaWYgZmlsdGVyZWRQYXJhbWV0ZXJzLmlzRW1wdHkgewogICAgICAgICAgICByZXR1cm4gInJldHVybiBcKHByZWZpeClQZXJmb3JtKG1ldGhvZDogLlwocHJvdG90eXBlKSwgcGVyZm9ybXM6IHBlcmZvcm0pIgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAicmV0dXJuIFwocHJlZml4KVBlcmZvcm0obWV0aG9kOiAuXChwcm90b3R5cGUpKFwocGFyYW1ldGVyc0ZvclByb3h5SW5pdCgpKSksIHBlcmZvcm1zOiBwZXJmb3JtKSIKICAgICAgICB9CiAgICB9CgogICAgZnVuYyBwZXJmb3JtUHJveHlDbG9zdXJlVHlwZSgpIC0+IFN0cmluZyB7CiAgICAgICAgaWYgZmlsdGVyZWRQYXJhbWV0ZXJzLmlzRW1wdHkgewogICAgICAgICAgICByZXR1cm4gIigpIC0+IFZvaWQiCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbGV0IHBhcmFtZXRlcnMgPSBzZWxmLnBhcmFtZXRlcnMKICAgICAgICAgICAgICAgIC5tYXAgeyAiXCgkMC5qdXN0UGVyZm9ybVR5cGUpIiB9CiAgICAgICAgICAgICAgICAuam9pbmVkKHNlcGFyYXRvcjogIiwgIikKICAgICAgICAgICAgcmV0dXJuICIoXChwYXJhbWV0ZXJzKSkgLT4gVm9pZCIKICAgICAgICB9CiAgICB9CgogICAgZnVuYyBwZXJmb3JtUHJveHlDbG9zdXJlQ2FsbCgpIC0+IFN0cmluZyB7CiAgICAgICAgaWYgZmlsdGVyZWRQYXJhbWV0ZXJzLmlzRW1wdHkgewogICAgICAgICAgICByZXR1cm4gInBlcmZvcm0/KCkiCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbGV0IHBhcmFtZXRlcnMgPSBmaWx0ZXJlZFBhcmFtZXRlcnMKICAgICAgICAgICAgICAgIC5tYXAgeyBwIGluCiAgICAgICAgICAgICAgICAgICAgbGV0IHdyYXBwZWQgPSBQYXJhbWV0ZXJXcmFwcGVyKHAsIHNlbGYuZ2V0VmFyaWFkaWNQYXJhbWV0ZXJzTmFtZXMoKSkKICAgICAgICAgICAgICAgICAgICBsZXQgaXNBdXRvbG9zdXJlID0gd3JhcHBlZC5qdXN0VHlwZS5oYXNQcmVmaXgoIkBhdXRvY2xvc3VyZSIpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJcKHAuaW5vdXQgPyAiJiIgOiAiIilgXChwLm5hbWUpYFwoaXNBdXRvbG9zdXJlID8gIigpIiA6ICIiKSIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC5qb2luZWQoc2VwYXJhdG9yOiAiLCAiKQogICAgICAgICAgICByZXR1cm4gInBlcmZvcm0/KFwocGFyYW1ldGVycykpIgogICAgICAgIH0KICAgIH0KCiAgICBmdW5jIHBlcmZvcm1DYWxsKCkgLT4gU3RyaW5nIHsKICAgICAgICBndWFyZCAhbWV0aG9kLmlzSW5pdGlhbGl6ZXIgZWxzZSB7IHJldHVybiAiIiB9CiAgICAgICAgbGV0IHR5cGUgPSBwZXJmb3JtUHJveHlDbG9zdXJlVHlwZSgpCiAgICAgICAgdmFyIHByb3h5ID0gZmlsdGVyZWRQYXJhbWV0ZXJzLmlzRW1wdHkgPyAiXChwcm90b3R5cGUpIiA6ICJcKHByb3RvdHlwZSkoXChwYXJhbWV0ZXJzRm9yTWV0aG9kQ2FsbCgpKSkiCgogICAgICAgIGxldCBjYXN0ID0gImxldCBwZXJmb3JtID0gbWV0aG9kUGVyZm9ybVZhbHVlKC5cKHByb3h5KSkgYXM/IFwodHlwZSkiCiAgICAgICAgbGV0IGNhbGwgPSBwZXJmb3JtUHJveHlDbG9zdXJlQ2FsbCgpCgogICAgICAgIHJldHVybiAiXG5cdFx0XChjYXN0KVxuXHRcdFwoY2FsbCkiCiAgICB9CgogICAgLy8gSGVscGVycwogICAgcHJpdmF0ZSBmdW5jIHBhcmFtZXRlcnNGb3JNZXRob2RDYWxsKCkgLT4gU3RyaW5nIHsKICAgICAgICBsZXQgZ2VuZXJpY3MgPSBnZXRHZW5lcmljc1dpdGhvdXRDb25zdHJhaW50cygpCiAgICAgICAgcmV0dXJuIHBhcmFtZXRlcnMubWFwIHsgJDAud3JhcHBlZEZvckNhbGxzKGdlbmVyaWNzLCBoYXNBdmFpbGFiaWxpdHkpIH0uam9pbmVkKHNlcGFyYXRvcjogIiwgIikKICAgIH0KCiAgICBwcml2YXRlIGZ1bmMgcGFyYW1ldGVyc0Zvck1ldGhvZFR5cGVEZWNsYXJhdGlvbihhdmFpbGFiaWxpdHk6IEJvb2wpIC0+IFN0cmluZyB7CiAgICAgICAgbGV0IGdlbmVyaWNzID0gZ2V0R2VuZXJpY3NXaXRob3V0Q29uc3RyYWludHMoKQogICAgICAgIHJldHVybiBwYXJhbWV0ZXJzLm1hcCB7IHBhcmFtIGluCiAgICAgICAgICAgIGlmIHBhcmFtLmlzR2VuZXJpYyhnZW5lcmljcykgeyByZXR1cm4gcGFyYW0uZ2VuZXJpY1R5cGUgfQogICAgICAgICAgICBpZiBhdmFpbGFiaWxpdHkgeyByZXR1cm4gcGFyYW0udHlwZUVyYXNlZFR5cGUgfQogICAgICAgICAgICByZXR1cm4gcmVwbGFjaW5nU2VsZihwYXJhbS5uZXN0ZWRUeXBlKQogICAgICAgIH0uam9pbmVkKHNlcGFyYXRvcjogIiwgIikKICAgIH0KCiAgICBwcml2YXRlIGZ1bmMgcGFyYW1ldGVyc0ZvclByb3h5U2lnbmF0dXJlKCkgLT4gU3RyaW5nIHsKICAgICAgICByZXR1cm4gcGFyYW1ldGVycy5tYXAgeyBwIGluCiAgICAgICAgICAgIHJldHVybiAiXChwLmxhYmVsQW5kTmFtZSgpKTogXChyZXBsYWNpbmdTZWxmKHAubmVzdGVkVHlwZSkpIgogICAgICAgIH0uam9pbmVkKHNlcGFyYXRvcjogIiwgIikKICAgIH0KCiAgICBwcml2YXRlIGZ1bmMgcGFyYW1ldGVyc0ZvclN0dWJTaWduYXR1cmUoKSAtPiBTdHJpbmcgewogICAgICAgIGZ1bmMgcmVwbGFjaW5nKGZpcnN0OiBTdHJpbmcsIGluIGZ1bGw6IFN0cmluZywgd2l0aCBvdGhlcjogU3RyaW5nKSAtPiBTdHJpbmcgewogICAgICAgICAgICBndWFyZCBsZXQgcmFuZ2UgPSBmdWxsLnJhbmdlKG9mOiBmaXJzdCkgZWxzZSB7IHJldHVybiBmdWxsIH0KICAgICAgICAgICAgcmV0dXJuIGZ1bGwucmVwbGFjaW5nQ2hhcmFjdGVycyhpbjogcmFuZ2UsIHdpdGg6IG90aGVyKQogICAgICAgIH0KICAgICAgICBsZXQgcHJlZml4ID0gbWV0aG9kLnNob3J0TmFtZQogICAgICAgIGxldCBmdWxsID0gbWV0aG9kLm5hbWUKICAgICAgICBsZXQgcmFuZ2UgPSBmdWxsLnJhbmdlKG9mOiBwcmVmaXgpIQogICAgICAgIHZhciB1bnJlZmluZWQgPSAiXChmdWxsW3JhbmdlLnVwcGVyQm91bmQuLi5dKSIKICAgICAgICBwYXJhbWV0ZXJzLm1hcCB7IHAgLT4gKFN0cmluZyxTdHJpbmcpIGluCiAgICAgICAgICAgIHJldHVybiAoIlwocC50eXBlKSIsIlwocC5qdXN0VHlwZSkiKQogICAgICAgIH0uZm9yRWFjaCB7CiAgICAgICAgICAgIHVucmVmaW5lZCA9IHJlcGxhY2luZyhmaXJzdDogJDAsIGluOiB1bnJlZmluZWQsIHdpdGg6ICQxKQogICAgICAgIH0KICAgICAgICByZXR1cm4gdW5yZWZpbmVkCiAgICB9CgogICAgcHJpdmF0ZSBmdW5jIHBhcmFtZXRlcnNGb3JQcm94eUluaXQoKSAtPiBTdHJpbmcgewogICAgICAgIGxldCBnZW5lcmljcyA9IGdldEdlbmVyaWNzV2l0aG91dENvbnN0cmFpbnRzKCkKICAgICAgICByZXR1cm4gcGFyYW1ldGVycy5tYXAgeyAiXCgkMC53cmFwcGVkRm9yUHJveHkoZ2VuZXJpY3MsIGhhc0F2YWlsYWJpbGl0eSkpIiB9LmpvaW5lZChzZXBhcmF0b3I6ICIsICIpCiAgICB9CgogICAgcHJpdmF0ZSBmdW5jIGlzR2VuZXJpYygpIC0+IEJvb2wgewogICAgICAgIHJldHVybiBtZXRob2Quc2hvcnROYW1lLmNvbnRhaW5zKCI8IikgJiYgbWV0aG9kLnNob3J0TmFtZS5jb250YWlucygiPiIpCiAgICB9CgogICAgcHJpdmF0ZSBmdW5jIGdldFZhcmlhZGljUGFyYW1ldGVyc05hbWVzKCkgLT4gW1N0cmluZ10gewogICAgICAgIGxldCBwYXR0ZXJuID0gIltcXCh8LF0oICpbX3xcXHddKiApPyAqKFxcdyspICpcXDogKiguKz9cXC5cXC5cXC4pIgogICAgICAgIGxldCBzdHIgPSBtZXRob2QubmFtZQogICAgICAgIGxldCByYW5nZSA9IE5TUmFuZ2UobG9jYXRpb246IDAsIGxlbmd0aDogKHN0ciBhcyBOU1N0cmluZykubGVuZ3RoKQoKICAgICAgICBndWFyZCBsZXQgcmVnZXggPSB0cnk/IE5TUmVndWxhckV4cHJlc3Npb24ocGF0dGVybjogcGF0dGVybikgZWxzZSB7IHJldHVybiBbXSB9CgogICAgICAgIHZhciByZXN1bHQ6IFtTdHJpbmddID0gcmVnZXgKICAgICAgICAgICAgLm1hdGNoZXMoaW46IHN0ciwgb3B0aW9uczogW10sIHJhbmdlOiByYW5nZSkKICAgICAgICAgICAgLmNvbXBhY3RNYXAgeyBtYXRjaCAtPiBTdHJpbmc/IGluCiAgICAgICAgICAgICAgICBndWFyZCBsZXQgbmFtZVJhbmdlID0gUmFuZ2UobWF0Y2gucmFuZ2UoYXQ6IDIpLCBpbjogc3RyKSBlbHNlIHsgcmV0dXJuIG5pbCB9CiAgICAgICAgICAgICAgICByZXR1cm4gU3RyaW5nKHN0cltuYW1lUmFuZ2VdKQogICAgICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdAogICAgfQoKICAgIC8vLyBSZXR1cm5zIGxpc3Qgb2YgZ2VuZXJpY3MgdXNlZCBpbiBtZXRob2Qgc2lnbmF0dXJlLCB3aXRob3V0IHRoZWlyIGNvbnN0cmFpbnRzIChsaWtlIFtULFUsVl0pCiAgICAvLy8KICAgIC8vLyAtIFJldHVybnM6IEFycmF5IG9mIHN0cmluZ3MsIHdoZXJlIGVhY2ggc3RyaW5ncyByZXByZXNlbnQgZ2VuZXJpYyBuYW1lCiAgICBwcml2YXRlIGZ1bmMgZ2V0R2VuZXJpY3NXaXRob3V0Q29uc3RyYWludHMoKSAtPiBbU3RyaW5nXSB7CiAgICAgICAgbGV0IG5hbWUgPSBtZXRob2Quc2hvcnROYW1lCiAgICAgICAgZ3VhcmQgbGV0IHN0YXJ0ID0gbmFtZS5pbmRleChvZjogIjwiKSwgbGV0IGVuZCA9IG5hbWUuaW5kZXgob2Y6ICI+IikgZWxzZSB7IHJldHVybiBbXSB9CgogICAgICAgIHZhciBnZW5QYXJ0ID0gbmFtZVtzdGFydC4uLmVuZF0KICAgICAgICBnZW5QYXJ0LnJlbW92ZUZpcnN0KCkKICAgICAgICBnZW5QYXJ0LnJlbW92ZUxhc3QoKQoKICAgICAgICBsZXQgcGFydHMgPSBnZW5QYXJ0LnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiICIsIHdpdGg6ICIiKS5jaGFyYWN0ZXJzLnNwbGl0KHNlcGFyYXRvcjogIiwiKS5tYXAoU3RyaW5nLmluaXQpCiAgICAgICAgcmV0dXJuIHBhcnRzLm1hcCB7IHN0cmlwR2VuUGFydChwYXJ0OiAkMCkgfQogICAgfQoKICAgIC8vLyBSZXR1cm5zIGxpc3Qgb2YgZ2VuZXJpYyBjb25zdHJhaW50ZXMgZnJvbSBtZXRob2Qgc2lnbmF0dXJlLiBEb2VzIG9ubHkgY29udGFpbiBzdHVmZiBiZXR3ZWVuICc8JyBhbmQgJz4nCiAgICAvLy8KICAgIC8vLyAtIFJldHVybnM6IEFycmF5IG9mIHN0cmluZ3MsIGxpa2UgWyJUOiBDb2RhYmxlIiwgIlU6IFdoYXRldmVyIl0KICAgIHByaXZhdGUgZnVuYyBnZXRHZW5lcmljc0NvbnN0cmFpbnRzKF8gZ2VuZXJpY3M6IFtTdHJpbmddLCBmaWx0ZXJTaW5nbGU6IEJvb2wgPSB0cnVlKSAtPiBbU3RyaW5nXSB7CiAgICAgICAgbGV0IG5hbWUgPSBtZXRob2Quc2hvcnROYW1lCiAgICAgICAgZ3VhcmQgbGV0IHN0YXJ0ID0gbmFtZS5pbmRleChvZjogIjwiKSwgbGV0IGVuZCA9IG5hbWUuaW5kZXgob2Y6ICI+IikgZWxzZSB7IHJldHVybiBbXSB9CgogICAgICAgIHZhciBnZW5QYXJ0ID0gbmFtZVtzdGFydC4uLmVuZF0KICAgICAgICBnZW5QYXJ0LnJlbW92ZUZpcnN0KCkKICAgICAgICBnZW5QYXJ0LnJlbW92ZUxhc3QoKQoKICAgICAgICBsZXQgcGFydHMgPSBnZW5QYXJ0LnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiICIsIHdpdGg6ICIiKS5jaGFyYWN0ZXJzLnNwbGl0KHNlcGFyYXRvcjogIiwiKS5tYXAoU3RyaW5nLmluaXQpCiAgICAgICAgcmV0dXJuIHBhcnRzLmZpbHRlciB7CiAgICAgICAgICAgIGxldCBjb21wb25lbnRzID0gJDAuY29tcG9uZW50cyhzZXBhcmF0ZWRCeTogIjoiKQogICAgICAgICAgICByZXR1cm4gKGNvbXBvbmVudHMuY291bnQgPT0gMiB8fCAhZmlsdGVyU2luZ2xlKSAmJiBnZW5lcmljcy5jb250YWlucyhjb21wb25lbnRzWzBdKQogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGZ1bmMgZ2V0R2VuZXJpY3NBbW9uZ1BhcmFtZXRlcnMoKSAtPiBbU3RyaW5nXSB7CiAgICAgICAgcmV0dXJuIGdldEdlbmVyaWNzV2l0aG91dENvbnN0cmFpbnRzKCkuZmlsdGVyIHsKICAgICAgICAgICAgZm9yIHBhcmFtIGluIHNlbGYucGFyYW1ldGVycyB7CiAgICAgICAgICAgICAgICBpZiBwYXJhbS5pc0dlbmVyaWMoWyQwXSkgeyByZXR1cm4gdHJ1ZSB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlCiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgZnVuYyB3cmFwR2VuZXJpY3MoXyBnZW5lcmljczogW1N0cmluZ10pIC0+IFN0cmluZyB7CiAgICAgICAgZ3VhcmQgIWdlbmVyaWNzLmlzRW1wdHkgZWxzZSB7IHJldHVybiAiIiB9CiAgICAgICAgcmV0dXJuICI8XChnZW5lcmljcy5qb2luZWQoc2VwYXJhdG9yOiIsIikpPiIKICAgIH0KCiAgICBwcml2YXRlIGZ1bmMgc3RyaXBHZW5QYXJ0KHBhcnQ6IFN0cmluZykgLT4gU3RyaW5nIHsKICAgICAgICByZXR1cm4gcGFydC5jaGFyYWN0ZXJzLnNwbGl0KHNlcGFyYXRvcjogIjoiKS5tYXAoU3RyaW5nLmluaXQpLmZpcnN0IQogICAgfQoKICAgIHByaXZhdGUgZnVuYyByZXR1cm5UeXBlU3RyaXBwZWQoXyBtZXRob2Q6IFNvdXJjZXJ5UnVudGltZS5NZXRob2QsIHR5cGU6IEJvb2wgPSBmYWxzZSkgLT4gU3RyaW5nIHsKICAgICAgICBsZXQgcmV0dXJuVHlwZVJhdyA9ICJcKG1ldGhvZC5yZXR1cm5UeXBlTmFtZSkiCiAgICAgICAgdmFyIHN0cmlwcGVkOiBTdHJpbmcgPSB7CiAgICAgICAgICAgIGd1YXJkIGxldCByYW5nZSA9IHJldHVyblR5cGVSYXcucmFuZ2Uob2Y6ICJ3aGVyZSIpIGVsc2UgeyByZXR1cm4gcmV0dXJuVHlwZVJhdyB9CiAgICAgICAgICAgIHZhciBzdHJpcHBlZCA9IHJldHVyblR5cGVSYXcKICAgICAgICAgICAgc3RyaXBwZWQucmVtb3ZlU3VicmFuZ2UoKHJhbmdlLmxvd2VyQm91bmQpLi4uKQogICAgICAgICAgICByZXR1cm4gc3RyaXBwZWQKICAgICAgICB9KCkKICAgICAgICBzdHJpcHBlZCA9IHN0cmlwcGVkLnRyaW1taW5nQ2hhcmFjdGVycyhpbjogQ2hhcmFjdGVyU2V0KGNoYXJhY3RlcnNJbjogIiAiKSkKICAgICAgICBndWFyZCB0eXBlIGVsc2UgeyByZXR1cm4gc3RyaXBwZWQgfQogICAgICAgIHJldHVybiAiKFwoc3RyaXBwZWQpKS5UeXBlIgogICAgfQoKICAgIHByaXZhdGUgZnVuYyB3aGVyZUNsYXVzZUNvbnN0cmFpbnRzKCkgLT4gW1N0cmluZ10gewogICAgICAgIGxldCByZXR1cm5UeXBlUmF3ID0gbWV0aG9kLnJldHVyblR5cGVOYW1lLm5hbWUKICAgICAgICBndWFyZCBsZXQgcmFuZ2UgPSByZXR1cm5UeXBlUmF3LnJhbmdlKG9mOiAid2hlcmUiKSBlbHNlIHsgcmV0dXJuIFtdIH0KICAgICAgICB2YXIgd2hlcmVDbGF1c2UgPSByZXR1cm5UeXBlUmF3CiAgICAgICAgd2hlcmVDbGF1c2UucmVtb3ZlU3VicmFuZ2UoLi4uKHJhbmdlLnVwcGVyQm91bmQpKQogICAgICAgIHJldHVybiB3aGVyZUNsYXVzZQogICAgICAgICAgICAudHJpbW1pbmdDaGFyYWN0ZXJzKGluOiBDaGFyYWN0ZXJTZXQud2hpdGVzcGFjZXNBbmROZXdsaW5lcykKICAgICAgICAgICAgLmNvbXBvbmVudHMoc2VwYXJhdGVkQnk6ICIsIikKICAgIH0KCiAgICBwcml2YXRlIGZ1bmMgd2hlcmVDbGF1c2VFeHByZXNzaW9uKCkgLT4gU3RyaW5nIHsKICAgICAgICBsZXQgY29uc3RyYWludHMgPSB3aGVyZUNsYXVzZUNvbnN0cmFpbnRzKCkKICAgICAgICBpZiBjb25zdHJhaW50cy5pc0VtcHR5IHsKICAgICAgICAgICAgcmV0dXJuICIiCiAgICAgICAgfQogICAgICAgIHJldHVybiAiIHdoZXJlICIgKyBjb25zdHJhaW50cy5qb2luZWQoc2VwYXJhdG9yOiAiLCAiKQogICAgfQoKICAgIHByaXZhdGUgZnVuYyBtZXRob2RJbmZvKCkgLT4gKGFubm90YXRpb246IFN0cmluZywgbWV0aG9kTmFtZTogU3RyaW5nLCBnZW5lcmljQ29uc3RyYWluczogU3RyaW5nKSB7CiAgICAgICAgbGV0IGdlbmVyaWNzID0gZ2V0R2VuZXJpY3NBbW9uZ1BhcmFtZXRlcnMoKQogICAgICAgIGxldCBtZXRob2ROYW1lID0gcmV0dXJuVHlwZU1hdHRlcnMoKSA/IG1ldGhvZC5zaG9ydE5hbWUgOiAiXChtZXRob2QuY2FsbE5hbWUpXCh3cmFwR2VuZXJpY3MoZ2VuZXJpY3MpKSIKICAgICAgICBsZXQgY29uc3RyYWludHM6IFN0cmluZyA9IHsKICAgICAgICAgICAgbGV0IGNvbnN0cmFpbnRzOiBbU3RyaW5nXQogICAgICAgICAgICBpZiByZXR1cm5UeXBlTWF0dGVycygpIHsKICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzID0gd2hlcmVDbGF1c2VDb25zdHJhaW50cygpCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBjb25zdHJhaW50cyA9IGdldEdlbmVyaWNzQ29uc3RyYWludHMoZ2VuZXJpY3MpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZ3VhcmQgIWNvbnN0cmFpbnRzLmlzRW1wdHkgZWxzZSB7IHJldHVybiAiIiB9CgogICAgICAgICAgICByZXR1cm4gIiB3aGVyZSBcKGNvbnN0cmFpbnRzLmpvaW5lZChzZXBhcmF0b3I6ICIsICIpKSIKICAgICAgICB9KCkKICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHNlbGYubWV0aG9kQXR0cmlidXRlc05vbk9iamMKICAgICAgICBhdHRyaWJ1dGVzID0gYXR0cmlidXRlcy5jb25kZW5zZVdoaXRlc3BhY2UoKQogICAgICAgIGF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzLmlzRW1wdHkgPyAiIiA6ICJcKGF0dHJpYnV0ZXMpXG5cdFx0IgogICAgICAgIHJldHVybiAoYXR0cmlidXRlcywgbWV0aG9kTmFtZSwgY29uc3RyYWludHMpCiAgICB9Cn0KCmV4dGVuc2lvbiBTdHJpbmcgewogICAgZnVuYyBjb25kZW5zZVdoaXRlc3BhY2UoKSAtPiBTdHJpbmcgewogICAgICAgIGxldCBjb21wb25lbnRzID0gc2VsZi5jb21wb25lbnRzKHNlcGFyYXRlZEJ5OiAud2hpdGVzcGFjZXNBbmROZXdsaW5lcykKICAgICAgICByZXR1cm4gY29tcG9uZW50cy5maWx0ZXIgeyAhJDAuaXNFbXB0eSB9LmpvaW5lZChzZXBhcmF0b3I6ICIgIikKICAgIH0KfQpjbGFzcyBTdWJzY3JpcHRXcmFwcGVyIHsKICAgIGxldCB3cmFwcGVkOiBTb3VyY2VyeVJ1bnRpbWUuU3Vic2NyaXB0CiAgICB2YXIgcmVhZG9ubHk6IEJvb2wgeyByZXR1cm4gIXdyYXBwZWQuaXNNdXRhYmxlIH0KICAgIHZhciB3cmFwcGVkUGFyYW1ldGVyczogW1BhcmFtZXRlcldyYXBwZXJdIHsgcmV0dXJuIHdyYXBwZWQucGFyYW1ldGVycy5tYXAgeyBQYXJhbWV0ZXJXcmFwcGVyKCQwKSB9IH0KICAgIHZhciBjYXNlc0NvdW50OiBJbnQgeyByZXR1cm4gcmVhZG9ubHkgPyAxIDogMiB9CiAgICB2YXIgbmVzdGVkVHlwZTogU3RyaW5nIHsgcmV0dXJuICJcKFR5cGVXcmFwcGVyKHdyYXBwZWQucmV0dXJuVHlwZU5hbWUpLm5lc3RlZFBhcmFtZXRlcikiIH0KICAgIGxldCBhc3NvY2lhdGVkVHlwZXM6IFtTdHJpbmddPwogICAgbGV0IGdlbmVyaWNUeXBlc0xpc3Q6IFtTdHJpbmddCiAgICBsZXQgZ2VuZXJpY1R5cGVzTW9kaWZpZXI6IFN0cmluZz8KICAgIGxldCB3aGVyZUNsYXVzZTogU3RyaW5nCiAgICB2YXIgaGFzQXZhaWxhYmlsaXR5OiBCb29sIHsgd3JhcHBlZC5hdHRyaWJ1dGVzWyJhdmFpbGFibGUiXT8uaXNFbXB0eSA9PSBmYWxzZSB9CgogICAgcHJpdmF0ZSB2YXIgbWV0aG9kQXR0cmlidXRlczogU3RyaW5nIHsKICAgICAgICByZXR1cm4gSGVscGVycy5leHRyYWN0QXR0cmlidXRlcyhmcm9tOiBzZWxmLndyYXBwZWQuYXR0cmlidXRlcywgZmlsdGVyT3V0U3RhcnRpbmdXaXRoOiBbIm11dGF0aW5nIiwgIkBpbmxpbmFibGUiXSkKICAgIH0KICAgIHByaXZhdGUgdmFyIG1ldGhvZEF0dHJpYnV0ZXNOb25PYmpjOiBTdHJpbmcgewogICAgICAgIHJldHVybiBIZWxwZXJzLmV4dHJhY3RBdHRyaWJ1dGVzKGZyb206IHNlbGYud3JhcHBlZC5hdHRyaWJ1dGVzLCBmaWx0ZXJPdXRTdGFydGluZ1dpdGg6IFsibXV0YXRpbmciLCAiQGlubGluYWJsZSIsICJAb2JqYyJdKQogICAgfQoKICAgIHByaXZhdGUgbGV0IG5vU3R1YkRlZmluZWRNZXNzYWdlID0gIlN0dWIgcmV0dXJuIHZhbHVlIG5vdCBzcGVjaWZpZWQgZm9yIHN1YnNjcmlwdC4gVXNlIGdpdmVuIGZpcnN0LiIKCiAgICBwcml2YXRlIHN0YXRpYyB2YXIgcmVnaXN0ZXJlZDogW1N0cmluZzogSW50XSA9IFs6XQogICAgcHJpdmF0ZSBzdGF0aWMgdmFyIG5hbWVzV2l0aG91dFJldHVyblR5cGU6IFtTdHJpbmc6IEludF0gPSBbOl0KICAgIHByaXZhdGUgc3RhdGljIHZhciBzdWZmaXhlczogW1N0cmluZzogSW50XSA9IFs6XQogICAgcHVibGljIHN0YXRpYyBmdW5jIGNsZWFyKCkgLT4gU3RyaW5nIHsKICAgICAgICBTdWJzY3JpcHRXcmFwcGVyLnJlZ2lzdGVyZWQgPSBbOl0KICAgICAgICBTdWJzY3JpcHRXcmFwcGVyLnN1ZmZpeGVzID0gWzpdCiAgICAgICAgbmFtZXNXaXRob3V0UmV0dXJuVHlwZSA9IFs6XQogICAgICAgIHJldHVybiAiIgogICAgfQogICAgc3RhdGljIGZ1bmMgcmVnaXN0ZXIoXyBuYW1lOiBTdHJpbmcsIF8gdW5pcXVlTmFtZTogU3RyaW5nKSB7CiAgICAgICAgbGV0IGNvdW50ID0gU3Vic2NyaXB0V3JhcHBlci5yZWdpc3RlcmVkW25hbWVdID8/IDAKICAgICAgICBTdWJzY3JpcHRXcmFwcGVyLnJlZ2lzdGVyZWRbbmFtZV0gPSBjb3VudCArIDEKICAgICAgICBTdWJzY3JpcHRXcmFwcGVyLnN1ZmZpeGVzW3VuaXF1ZU5hbWVdID0gY291bnQgKyAxCiAgICB9CiAgICBzdGF0aWMgZnVuYyByZWdpc3RlcihzaG9ydCBuYW1lOiBTdHJpbmcpIHsKICAgICAgICBsZXQgY291bnQgPSBTdWJzY3JpcHRXcmFwcGVyLm5hbWVzV2l0aG91dFJldHVyblR5cGVbbmFtZV0gPz8gMAogICAgICAgIFN1YnNjcmlwdFdyYXBwZXIubmFtZXNXaXRob3V0UmV0dXJuVHlwZVtuYW1lXSA9IGNvdW50ICsgMQogICAgfQoKICAgIGZ1bmMgcmVnaXN0ZXIoKSB7CiAgICAgICAgU3Vic2NyaXB0V3JhcHBlci5yZWdpc3RlcihyZWdpc3RyYXRpb25OYW1lKCJnZXQiKSx1bmlxdWVOYW1lKQogICAgICAgIFN1YnNjcmlwdFdyYXBwZXIucmVnaXN0ZXIoc2hvcnQ6IHNob3J0TmFtZSkKICAgICAgICBndWFyZCAhcmVhZG9ubHkgZWxzZSB7IHJldHVybiB9CiAgICAgICAgU3Vic2NyaXB0V3JhcHBlci5yZWdpc3RlcihyZWdpc3RyYXRpb25OYW1lKCJzZXQiKSx1bmlxdWVOYW1lKQogICAgfQoKICAgIGluaXQoXyB3cmFwcGVkOiBTb3VyY2VyeVJ1bnRpbWUuU3Vic2NyaXB0KSB7CiAgICAgICAgc2VsZi53cmFwcGVkID0gd3JhcHBlZAogICAgICAgIGFzc29jaWF0ZWRUeXBlcyA9IEhlbHBlcnMuZXh0cmFjdEFzc29jaWF0ZWRUeXBlcyhmcm9tOiB3cmFwcGVkKQogICAgICAgIGdlbmVyaWNUeXBlc0xpc3QgPSBIZWxwZXJzLmV4dHJhY3RHZW5lcmljc0xpc3QoYXNzb2NpYXRlZFR5cGVzKQogICAgICAgIHdoZXJlQ2xhdXNlID0gSGVscGVycy5leHRyYWN0V2hlcmVDbGF1c2UoZnJvbTogd3JhcHBlZCkgPz8gIiIKICAgICAgICBpZiBsZXQgdHlwZXMgPSBhc3NvY2lhdGVkVHlwZXMgewogICAgICAgICAgICBnZW5lcmljVHlwZXNNb2RpZmllciA9ICI8XCh0eXBlcy5qb2luZWQoc2VwYXJhdG9yOiAiLCIpKT4iCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZ2VuZXJpY1R5cGVzTW9kaWZpZXIgPSBuaWwKICAgICAgICB9CiAgICB9CgogICAgZnVuYyByZWdpc3RyYXRpb25OYW1lKF8gYWNjZXNzb3I6IFN0cmluZykgLT4gU3RyaW5nIHsKICAgICAgICByZXR1cm4gInN1YnNjcmlwdF9cKGFjY2Vzc29yKV9cKHdyYXBwZWRQYXJhbWV0ZXJzLm1hcCh7ICQwLnNhbml0aXplZEZvckVudW1DYXNlTmFtZSgpIH0pLmpvaW5lZChzZXBhcmF0b3I6ICJfIikpIgogICAgfQogICAgdmFyIHNob3J0TmFtZTogU3RyaW5nIHsgcmV0dXJuICJwdWJsaWMgc3Vic2NyaXB0XChnZW5lcmljVHlwZXNNb2RpZmllciA/PyAiICIpKFwod3JhcHBlZFBhcmFtZXRlcnMubWFwKHsgJDAuYXNNZXRob2RBcmd1bWVudCgpIH0pLmpvaW5lZChzZXBhcmF0b3I6ICIsICIpKSkiIH0KICAgIHZhciB1bmlxdWVOYW1lOiBTdHJpbmcgeyByZXR1cm4gIlwoc2hvcnROYW1lKSAtPiBcKHdyYXBwZWQucmV0dXJuVHlwZU5hbWUpXChzZWxmLndoZXJlQ2xhdXNlKSIgfQoKICAgIHByaXZhdGUgZnVuYyBuYW1lU3VmZml4KF8gYWNjZXNzb3I6IFN0cmluZykgLT4gU3RyaW5nIHsKICAgICAgICBndWFyZCBsZXQgY291bnQgPSBTdWJzY3JpcHRXcmFwcGVyLnJlZ2lzdGVyZWRbcmVnaXN0cmF0aW9uTmFtZShhY2Nlc3NvcildIGVsc2UgeyByZXR1cm4gIiIgfQogICAgICAgIGd1YXJkIGNvdW50ID4gMSBlbHNlIHsgcmV0dXJuICIiIH0KICAgICAgICBndWFyZCBsZXQgaW5kZXggPSBTdWJzY3JpcHRXcmFwcGVyLnN1ZmZpeGVzW3VuaXF1ZU5hbWVdIGVsc2UgeyByZXR1cm4gIiIgfQogICAgICAgIHJldHVybiAiX1woaW5kZXgpIgogICAgfQoKICAgIC8vIGNhbGwKICAgIGZ1bmMgc3Vic2NyaXB0Q2FsbCgpIC0+IFN0cmluZyB7CiAgICAgICAgbGV0IGdldCA9ICJcblx0XHRnZXQge1woZ2V0dGVyKCkpXG5cdFx0fSIKICAgICAgICBsZXQgc2V0ID0gcmVhZG9ubHkgPyAiIiA6ICJcblx0XHRzZXQge1woc2V0dGVyKCkpXG5cdFx0fSIKICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHNlbGYubWV0aG9kQXR0cmlidXRlc05vbk9iamMKICAgICAgICBhdHRyaWJ1dGVzID0gYXR0cmlidXRlcy5pc0VtcHR5ID8gIiIgOiAiXChhdHRyaWJ1dGVzKVxuXHQiCiAgICAgICAgcmV0dXJuICJcKGF0dHJpYnV0ZXMpXCh1bmlxdWVOYW1lKSB7XChnZXQpXChzZXQpXG5cdH0iCiAgICB9CiAgICBwcml2YXRlIGZ1bmMgZ2V0dGVyKCkgLT4gU3RyaW5nIHsKICAgICAgICBsZXQgbWV0aG9kID0gIi5cKHN1YnNjcmlwdENhc2VQcmVmaXgoImdldCIpKShcKHBhcmFtZXRlcnNGb3JNZXRob2RDYWxsKCkpKSIKICAgICAgICBsZXQgb3B0aW9uYWxSZXR1cm5Xb3JrYXJvdW5kID0gIlwod3JhcHBlZC5yZXR1cm5UeXBlTmFtZSkiLmhhc1N1ZmZpeCgiPyIpCiAgICAgICAgbGV0IG5vU3R1YkRlZmluZWQgPSAob3B0aW9uYWxSZXR1cm5Xb3JrYXJvdW5kIHx8IHdyYXBwZWQucmV0dXJuVHlwZU5hbWUuaXNPcHRpb25hbCkgPyAicmV0dXJuIG5pbCIgOiAib25GYXRhbEZhaWx1cmUoXCJcKG5vU3R1YkRlZmluZWRNZXNzYWdlKVwiKTsgRmFpbHVyZShcIm5vU3R1YkRlZmluZWRNZXNzYWdlXCIpIgogICAgICAgIHJldHVybgogICAgICAgICAgICAiXG5cdFx0XHRhZGRJbnZvY2F0aW9uKFwobWV0aG9kKSkiICsKICAgICAgICAgICAgICAgICJcblx0XHRcdGRvIHsiICsKICAgICAgICAgICAgICAgICJcblx0XHRcdFx0cmV0dXJuIHRyeSBtZXRob2RSZXR1cm5WYWx1ZShcKG1ldGhvZCkpLmNhc3RlZCgpIiArCiAgICAgICAgICAgICAgICAiXG5cdFx0XHR9IGNhdGNoIHsiICsKICAgICAgICAgICAgICAgICJcblx0XHRcdFx0XChub1N0dWJEZWZpbmVkKSIgKwogICAgICAgICJcblx0XHRcdH0iCiAgICB9CiAgICBwcml2YXRlIGZ1bmMgc2V0dGVyKCkgLT4gU3RyaW5nIHsKICAgICAgICBsZXQgbWV0aG9kID0gIi5cKHN1YnNjcmlwdENhc2VQcmVmaXgoInNldCIpKShcKHBhcmFtZXRlcnNGb3JNZXRob2RDYWxsKHNldDogdHJ1ZSkpKSIKICAgICAgICByZXR1cm4gIlxuXHRcdFx0YWRkSW52b2NhdGlvbihcKG1ldGhvZCkpIgogICAgfQoKICAgIHZhciBhc3NlcnRpb25OYW1lOiBTdHJpbmcgewogICAgICAgIHJldHVybiByZWFkb25seSA/IGFzc2VydGlvbk5hbWUoImdldCIpIDogIlwoYXNzZXJ0aW9uTmFtZSgiZ2V0IikpXG5cdFx0XHRcKGFzc2VydGlvbk5hbWUoInNldCIpKSIKICAgIH0KICAgIHByaXZhdGUgZnVuYyBhc3NlcnRpb25OYW1lKF8gYWNjZXNzb3I6IFN0cmluZykgLT4gU3RyaW5nIHsKICAgICAgICByZXR1cm4gImNhc2UgLlwoc3Vic2NyaXB0Q2FzZVByZWZpeChhY2Nlc3NvcikpOiByZXR1cm4gIiArCiAgICAgICAgICAgICJcIltcKGFjY2Vzc29yKV0gYHN1YnNjcmlwdGBcKGdlbmVyaWNUeXBlc01vZGlmaWVyID8/ICIiKVtcKHBhcmFtZXRlcnNGb3JBc3NlcnRpb25OYW1lKCkpXVwiIgogICAgfQoKICAgIC8vIG1ldGhvZCB0eXBlCiAgICBmdW5jIHN1YnNjcmlwdENhc2VQcmVmaXgoXyBhY2Nlc3NvcjogU3RyaW5nKSAtPiBTdHJpbmcgewogICAgICAgIHJldHVybiAiXChyZWdpc3RyYXRpb25OYW1lKGFjY2Vzc29yKSlcKG5hbWVTdWZmaXgoYWNjZXNzb3IpKSIKICAgIH0KICAgIGZ1bmMgc3Vic2NyaXB0Q2FzZU5hbWUoXyBhY2Nlc3NvcjogU3RyaW5nLCBhdmFpbGFiaWxpdHk6IEJvb2wgPSBmYWxzZSkgLT4gU3RyaW5nIHsKICAgICAgICByZXR1cm4gIlwoc3Vic2NyaXB0Q2FzZVByZWZpeChhY2Nlc3NvcikpKFwocGFyYW1ldGVyc0Zvck1ldGhvZFR5cGVEZWNsYXJhdGlvbihhdmFpbGFiaWxpdHk6IGF2YWlsYWJpbGl0eSwgc2V0OiBhY2Nlc3NvciA9PSAic2V0IikpKSIKICAgIH0KICAgIGZ1bmMgc3Vic2NyaXB0Q2FzZXMoKSAtPiBTdHJpbmcgewogICAgICAgIGlmIHJlYWRvbmx5IHsKICAgICAgICAgICAgcmV0dXJuICJjYXNlIFwoc3Vic2NyaXB0Q2FzZU5hbWUoImdldCIsIGF2YWlsYWJpbGl0eTogaGFzQXZhaWxhYmlsaXR5KSkiCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuICJjYXNlIFwoc3Vic2NyaXB0Q2FzZU5hbWUoImdldCIsIGF2YWlsYWJpbGl0eTogaGFzQXZhaWxhYmlsaXR5KSlcblx0XHRjYXNlIFwoc3Vic2NyaXB0Q2FzZU5hbWUoInNldCIsIGF2YWlsYWJpbGl0eTogaGFzQXZhaWxhYmlsaXR5KSkiCiAgICAgICAgfQogICAgfQogICAgZnVuYyBlcXVhbENhc2UoXyBhY2Nlc3NvcjogU3RyaW5nKSAtPiBTdHJpbmcgewogICAgICAgIHZhciBsaHNQYXJhbXMgPSB3cmFwcGVkLnBhcmFtZXRlcnMubWFwIHsgImxoc1woJDAubmFtZS5jYXBpdGFsaXplZCkiIH0uam9pbmVkKHNlcGFyYXRvcjogIiwgIikKICAgICAgICB2YXIgcmhzUGFyYW1zID0gd3JhcHBlZC5wYXJhbWV0ZXJzLm1hcCB7ICJyaHNcKCQwLm5hbWUuY2FwaXRhbGl6ZWQpIiB9LmpvaW5lZChzZXBhcmF0b3I6ICIsICIpCiAgICAgICAgdmFyIGNvbXBhcmF0b3JzID0gIlx0XHRcdFx0dmFyIHJlc3VsdHM6IFtNYXRjaGVyLlBhcmFtZXRlckNvbXBhcmlzb25SZXN1bHRdID0gW11cbiIKICAgICAgICBjb21wYXJhdG9ycyArPSB3cmFwcGVkUGFyYW1ldGVycy5tYXAgeyAiXHRcdFx0XHRcKCQwLmNvbXBhcmF0b3JSZXN1bHQoKSkiIH0uam9pbmVkKHNlcGFyYXRvcjogIlxuIikKCiAgICAgICAgaWYgYWNjZXNzb3IgPT0gInNldCIgewogICAgICAgICAgICBsaHNQYXJhbXMgKz0gIiwgbGhzRGlkU2V0IgogICAgICAgICAgICByaHNQYXJhbXMgKz0gIiwgcmhzRGlkU2V0IgogICAgICAgICAgICBjb21wYXJhdG9ycyArPSAiXG5cdFx0XHRcdHJlc3VsdHMuYXBwZW5kKE1hdGNoZXIuUGFyYW1ldGVyQ29tcGFyaXNvblJlc3VsdChQYXJhbWV0ZXIuY29tcGFyZShsaHM6IGxoc0RpZFNldCwgcmhzOiByaHNEaWRTZXQsIHdpdGg6IG1hdGNoZXIpLCBsaHNEaWRTZXQsIHJoc0RpZFNldCwgXCJuZXdWYWx1ZVwiKSkiCiAgICAgICAgfQoKICAgICAgICBjb21wYXJhdG9ycyArPSAiXG5cdFx0XHRcdHJldHVybiBNYXRjaGVyLkNvbXBhcmlzb25SZXN1bHQocmVzdWx0cykiCgogICAgICAgIC8vIGNvbXBhcmF0b3JSZXN1bHQoKQogICAgICAgIHJldHVybiAiY2FzZSAobGV0IC5cKHN1YnNjcmlwdENhc2VQcmVmaXgoYWNjZXNzb3IpKShcKGxoc1BhcmFtcykpLCBsZXQgLlwoc3Vic2NyaXB0Q2FzZVByZWZpeChhY2Nlc3NvcikpKFwocmhzUGFyYW1zKSkpOlxuIiArIGNvbXBhcmF0b3JzCiAgICB9CiAgICBmdW5jIGVxdWFsQ2FzZXMoKSAtPiBTdHJpbmcgewogICAgICAgIHJldHVybiByZWFkb25seSA/IGVxdWFsQ2FzZSgiZ2V0IikgOiAiXChlcXVhbENhc2UoImdldCIpKVxuXHRcdFx0XChlcXVhbENhc2UoInNldCIpKSIKICAgIH0KICAgIGZ1bmMgaW50VmFsdWVDYXNlKCkgLT4gU3RyaW5nIHsKICAgICAgICByZXR1cm4gcmVhZG9ubHkgPyBpbnRWYWx1ZUNhc2UoImdldCIpIDogIlwoaW50VmFsdWVDYXNlKCJnZXQiKSlcblx0XHRcdFwoaW50VmFsdWVDYXNlKCJzZXQiKSkiCiAgICB9CiAgICBmdW5jIGludFZhbHVlQ2FzZShfIGFjY2Vzc29yOiBTdHJpbmcpIC0+IFN0cmluZyB7CiAgICAgICAgbGV0IHBhcmFtcyA9IHdyYXBwZWRQYXJhbWV0ZXJzLmVudW1lcmF0ZWQoKS5tYXAgeyBvZmZzZXQsIF8gaW4KICAgICAgICAgICAgcmV0dXJuICJwXChvZmZzZXQpIgogICAgICAgIH0KICAgICAgICBsZXQgZGVmaW5pdGlvbnMgPSBwYXJhbXMuam9pbmVkKHNlcGFyYXRvcjogIiwgIikgKyAoYWNjZXNzb3IgPT0gInNldCIgPyAiLCBfIiA6ICIiKQogICAgICAgIGxldCBwYXJhbXNTdW0gPSBwYXJhbXMubWFwKHsgIlwoJDApLmludFZhbHVlIiB9KS5qb2luZWQoc2VwYXJhdG9yOiAiICsgIikKICAgICAgICByZXR1cm4gImNhc2UgbGV0IC5cKHN1YnNjcmlwdENhc2VQcmVmaXgoYWNjZXNzb3IpKShcKGRlZmluaXRpb25zKSk6IHJldHVybiBcKHBhcmFtc1N1bSkiCiAgICB9CgogICAgLy8gR2l2ZW4KICAgIGZ1bmMgZ2l2ZW5Db25zdHJ1Y3Rvck5hbWUoKSAtPiBTdHJpbmcgewogICAgICAgIGxldCByZXR1cm5UeXBlU3RyaW5nID0gcmV0dXJuc1NlbGYgPyByZXBsYWNlU2VsZiA6IFR5cGVXcmFwcGVyKHdyYXBwZWQucmV0dXJuVHlwZU5hbWUpLnN0cmlwcGVkCiAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSBzZWxmLm1ldGhvZEF0dHJpYnV0ZXNOb25PYmpjCiAgICAgICAgYXR0cmlidXRlcyA9IGF0dHJpYnV0ZXMuaXNFbXB0eSA/ICIiIDogIlwoYXR0cmlidXRlcylcblx0XHQiCiAgICAgICAgcmV0dXJuICJcKGF0dHJpYnV0ZXMpcHVibGljIHN0YXRpYyBmdW5jIGBzdWJzY3JpcHRgXChnZW5lcmljVHlwZXNNb2RpZmllciA/PyAiIikoXChwYXJhbWV0ZXJzRm9yUHJveHlTaWduYXR1cmUoKSksIHdpbGxSZXR1cm46IFwocmV0dXJuVHlwZVN0cmluZykuLi4pIC0+IFN1YnNjcmlwdFN0dWIiCiAgICB9CiAgICBmdW5jIGdpdmVuQ29uc3RydWN0b3IoKSAtPiBTdHJpbmcgewogICAgICAgIHJldHVybiAicmV0dXJuIEdpdmVuKG1ldGhvZDogLlwoc3Vic2NyaXB0Q2FzZVByZWZpeCgiZ2V0IikpKFwocGFyYW1ldGVyc0ZvclByb3h5SW5pdCgpKSksIHByb2R1Y3RzOiB3aWxsUmV0dXJuLm1hcCh7IFN0dWJQcm9kdWN0LnJldHVybigkMCBhcyBBbnkpIH0pKSIKICAgIH0KCiAgICAvLyBWZXJpZnkKICAgIGZ1bmMgdmVyaWZ5Q29uc3RydWN0b3JOYW1lKHNldDogQm9vbCA9IGZhbHNlKSAtPiBTdHJpbmcgewogICAgICAgIGxldCByZXR1cm5UeXBlU3RyaW5nID0gcmV0dXJuc1NlbGYgPyByZXBsYWNlU2VsZiA6IG5lc3RlZFR5cGUKICAgICAgICBsZXQgcmV0dXJuaW5nID0gc2V0ID8gIiIgOiByZXR1cm5pbmdQYXJhbWV0ZXIodHJ1ZSwgdHJ1ZSkKICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHNlbGYubWV0aG9kQXR0cmlidXRlc05vbk9iamMKICAgICAgICBhdHRyaWJ1dGVzID0gYXR0cmlidXRlcy5pc0VtcHR5ID8gIiIgOiAiXChhdHRyaWJ1dGVzKVxuXHRcdCIKICAgICAgICByZXR1cm4gIlwoYXR0cmlidXRlcylwdWJsaWMgc3RhdGljIGZ1bmMgYHN1YnNjcmlwdGBcKGdlbmVyaWNUeXBlc01vZGlmaWVyID8/ICIiKShcKHBhcmFtZXRlcnNGb3JQcm94eVNpZ25hdHVyZSgpKVwocmV0dXJuaW5nKVwoc2V0ID8gIiwgc2V0IG5ld1ZhbHVlOiBcKHJldHVyblR5cGVTdHJpbmcpIiA6ICIiKSkgLT4gVmVyaWZ5IgogICAgfQogICAgZnVuYyB2ZXJpZnlDb25zdHJ1Y3RvcihzZXQ6IEJvb2wgPSBmYWxzZSkgLT4gU3RyaW5nIHsKICAgICAgICByZXR1cm4gInJldHVybiBWZXJpZnkobWV0aG9kOiAuXChzdWJzY3JpcHRDYXNlUHJlZml4KHNldCA/ICJzZXQiIDogImdldCIpKShcKHBhcmFtZXRlcnNGb3JQcm94eUluaXQoc2V0OiBzZXQpKSkpIgogICAgfQoKICAgIC8vIEdlbmVyaWNzCiAgICBwcml2YXRlIGZ1bmMgZ2V0R2VuZXJpY3MoKSAtPiBbU3RyaW5nXSB7CiAgICAgICAgcmV0dXJuIGdlbmVyaWNUeXBlc0xpc3QKICAgIH0KCiAgICAvLyBIZWxwZXJzCiAgICBwcml2YXRlIHZhciByZXR1cm5zU2VsZjogQm9vbCB7IHJldHVybiBUeXBlV3JhcHBlcih3cmFwcGVkLnJldHVyblR5cGVOYW1lKS5pc1NlbGZUeXBlIH0KICAgIHByaXZhdGUgdmFyIHJlcGxhY2VTZWxmOiBTdHJpbmcgeyByZXR1cm4gQ3VycmVudC5zZWxmVHlwZSB9CiAgICBwcml2YXRlIGZ1bmMgcmV0dXJuVHlwZVN0cmlwcGVkKHR5cGU6IEJvb2wgPSBmYWxzZSkgLT4gU3RyaW5nIHsKICAgICAgICBsZXQgcmV0dXJuVHlwZVJhdyA9ICJcKHdyYXBwZWQucmV0dXJuVHlwZU5hbWUpIgogICAgICAgIHZhciBzdHJpcHBlZDogU3RyaW5nID0gewogICAgICAgICAgICBndWFyZCBsZXQgcmFuZ2UgPSByZXR1cm5UeXBlUmF3LnJhbmdlKG9mOiAid2hlcmUiKSBlbHNlIHsgcmV0dXJuIHJldHVyblR5cGVSYXcgfQogICAgICAgICAgICB2YXIgc3RyaXBwZWQgPSByZXR1cm5UeXBlUmF3CiAgICAgICAgICAgIHN0cmlwcGVkLnJlbW92ZVN1YnJhbmdlKChyYW5nZS5sb3dlckJvdW5kKS4uLikKICAgICAgICAgICAgcmV0dXJuIHN0cmlwcGVkCiAgICAgICAgfSgpCiAgICAgICAgc3RyaXBwZWQgPSBzdHJpcHBlZC50cmltbWluZ0NoYXJhY3RlcnMoaW46IENoYXJhY3RlclNldChjaGFyYWN0ZXJzSW46ICIgIikpCiAgICAgICAgZ3VhcmQgdHlwZSBlbHNlIHsgcmV0dXJuIHN0cmlwcGVkIH0KICAgICAgICByZXR1cm4gIihcKHN0cmlwcGVkKSkuVHlwZSIKICAgIH0KICAgIHByaXZhdGUgZnVuYyByZXR1cm5UeXBlTWF0dGVycygpIC0+IEJvb2wgewogICAgICAgIGxldCBjb3VudCA9IFN1YnNjcmlwdFdyYXBwZXIubmFtZXNXaXRob3V0UmV0dXJuVHlwZVtzaG9ydE5hbWVdID8/IDAKICAgICAgICByZXR1cm4gY291bnQgPiAxCiAgICB9CgogICAgLy8gcGFyYW1zCiAgICBwcml2YXRlIGZ1bmMgcmV0dXJuaW5nUGFyYW1ldGVyKF8gbXVsdGlwbGU6IEJvb2wsIF8gZnJvbnQ6IEJvb2wpIC0+IFN0cmluZyB7CiAgICAgICAgZ3VhcmQgcmV0dXJuVHlwZU1hdHRlcnMoKSBlbHNlIHsgcmV0dXJuICIiIH0KICAgICAgICBsZXQgcmV0dXJuaW5nOiBTdHJpbmcgPSAicmV0dXJuaW5nOiBcKHJldHVyblR5cGVTdHJpcHBlZCh0eXBlOiB0cnVlKSkiCiAgICAgICAgZ3VhcmQgbXVsdGlwbGUgZWxzZSB7IHJldHVybiByZXR1cm5pbmcgfQogICAgICAgIHJldHVybiBmcm9udCA/ICIsIFwocmV0dXJuaW5nKSIgOiAiXChyZXR1cm5pbmcpLCAiCiAgICB9CiAgICBwcml2YXRlIGZ1bmMgcGFyYW1ldGVyc0Zvck1ldGhvZFR5cGVEZWNsYXJhdGlvbihhdmFpbGFiaWxpdHk6IEJvb2wgPSBmYWxzZSwgc2V0OiBCb29sID0gZmFsc2UpIC0+IFN0cmluZyB7CiAgICAgICAgbGV0IGdlbmVyaWNzOiBbU3RyaW5nXSA9IGdldEdlbmVyaWNzKCkKICAgICAgICBsZXQgcGFyYW1zID0gd3JhcHBlZFBhcmFtZXRlcnMubWFwIHsgcGFyYW0gaW4KICAgICAgICAgICAgaWYgcGFyYW0uaXNHZW5lcmljKGdlbmVyaWNzKSB7IHJldHVybiBwYXJhbS5nZW5lcmljVHlwZSB9CiAgICAgICAgICAgIGlmIGF2YWlsYWJpbGl0eSB7IHJldHVybiBwYXJhbS50eXBlRXJhc2VkVHlwZSB9CiAgICAgICAgICAgIHJldHVybiBwYXJhbS5uZXN0ZWRUeXBlCiAgICAgICAgfS5qb2luZWQoc2VwYXJhdG9yOiAiLCAiKQogICAgICAgIGd1YXJkIHNldCBlbHNlIHsgcmV0dXJuIHBhcmFtcyB9CiAgICAgICAgbGV0IG5ld1ZhbHVlID0gVHlwZVdyYXBwZXIod3JhcHBlZC5yZXR1cm5UeXBlTmFtZSkuaXNHZW5lcmljKGdlbmVyaWNzKSA/ICJQYXJhbWV0ZXI8R2VuZXJpY0F0dHJpYnV0ZT4iIDogbmVzdGVkVHlwZQogICAgICAgIHJldHVybiAiXChwYXJhbXMpLCBcKG5ld1ZhbHVlKSIKICAgIH0KICAgIHByaXZhdGUgZnVuYyBwYXJhbWV0ZXJzRm9yUHJveHlJbml0KHNldDogQm9vbCA9IGZhbHNlKSAtPiBTdHJpbmcgewogICAgICAgIGxldCBnZW5lcmljcyA9IGdldEdlbmVyaWNzKCkKICAgICAgICBsZXQgbmV3VmFsdWUgPSBUeXBlV3JhcHBlcih3cmFwcGVkLnJldHVyblR5cGVOYW1lKS5pc0dlbmVyaWMoZ2VuZXJpY3MpID8gIm5ld1ZhbHVlLndyYXBBc0dlbmVyaWMoKSIgOiAibmV3VmFsdWUiCiAgICAgICAgcmV0dXJuIHdyYXBwZWRQYXJhbWV0ZXJzLm1hcCB7ICJcKCQwLndyYXBwZWRGb3JQcm94eShnZW5lcmljcywgaGFzQXZhaWxhYmlsaXR5KSkiIH0uam9pbmVkKHNlcGFyYXRvcjogIiwgIikgKyAoc2V0ID8gIiwgXChuZXdWYWx1ZSkiIDogIiIpCiAgICB9CiAgICBwcml2YXRlIGZ1bmMgcGFyYW1ldGVyc0ZvclByb3h5U2lnbmF0dXJlKHNldDogQm9vbCA9IGZhbHNlKSAtPiBTdHJpbmcgewogICAgICAgIHJldHVybiB3cmFwcGVkUGFyYW1ldGVycy5tYXAgeyAiXCgkMC5sYWJlbEFuZE5hbWUoKSk6IFwoJDAubmVzdGVkVHlwZSkiIH0uam9pbmVkKHNlcGFyYXRvcjogIiwgIikgKyAoc2V0ID8gIiwgc2V0IG5ld1ZhbHVlOiBcKG5lc3RlZFR5cGUpIiA6ICIiKQogICAgfQogICAgcHJpdmF0ZSBmdW5jIHBhcmFtZXRlcnNGb3JBc3NlcnRpb25OYW1lKCkgLT4gU3RyaW5nIHsKICAgICAgICByZXR1cm4gd3JhcHBlZFBhcmFtZXRlcnMubWFwIHsgIlwoJDAubGFiZWxBbmROYW1lKCkpIiB9LmpvaW5lZChzZXBhcmF0b3I6ICIsICIpCiAgICB9CiAgICBwcml2YXRlIGZ1bmMgcGFyYW1ldGVyc0Zvck1ldGhvZENhbGwoc2V0OiBCb29sID0gZmFsc2UpIC0+IFN0cmluZyB7CiAgICAgICAgbGV0IGdlbmVyaWNzID0gZ2V0R2VuZXJpY3MoKQogICAgICAgIGxldCBwYXJhbXMgPSB3cmFwcGVkUGFyYW1ldGVycy5tYXAgeyAkMC53cmFwcGVkRm9yQ2FsbHMoZ2VuZXJpY3MsIGhhc0F2YWlsYWJpbGl0eSkgfS5qb2luZWQoc2VwYXJhdG9yOiAiLCAiKQogICAgICAgIGxldCBwb3N0Zml4ID0gVHlwZVdyYXBwZXIod3JhcHBlZC5yZXR1cm5UeXBlTmFtZSkuaXNHZW5lcmljKGdlbmVyaWNzKSA/ICIud3JhcEFzR2VuZXJpYygpIiA6ICIiCiAgICAgICAgcmV0dXJuICFzZXQgPyBwYXJhbXMgOiAiXChwYXJhbXMpLCBcKG5lc3RlZFR5cGUpLnZhbHVlKG5ld1ZhbHVlKVwocG9zdGZpeCkiCiAgICB9Cn0KY2xhc3MgVmFyaWFibGVXcmFwcGVyIHsKICAgIGxldCB2YXJpYWJsZTogU291cmNlcnlSdW50aW1lLlZhcmlhYmxlCiAgICBsZXQgc2NvcGU6IFN0cmluZwogICAgdmFyIHJlYWRvbmx5OiBCb29sIHsgcmV0dXJuIHZhcmlhYmxlLndyaXRlQWNjZXNzLmlzRW1wdHkgfQogICAgdmFyIHByaXZhdGVQcm90b3R5cGVOYW1lOiBTdHJpbmcgeyByZXR1cm4gIl9fcF9cKHZhcmlhYmxlLm5hbWUpIi5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogImAiLCB3aXRoOiAiIikgfQogICAgdmFyIGNhc2VzQ291bnQ6IEludCB7IHJldHVybiByZWFkb25seSA/IDEgOiAyIH0KCiAgICB2YXIgYWNjZXNzTW9kaWZpZXI6IFN0cmluZyB7CiAgICAgICAgLy8gVE9ETzogRml4IGFjY2VzcyBsZXZlbHMgZm9yIFN3aWZ0eVByb3RvdHlwZQogICAgICAgIC8vIGd1YXJkIHZhcmlhYmxlLnR5cGU/LmFjY2Vzc0xldmVsICE9ICJpbnRlcm5hbCIgZWxzZSB7IHJldHVybiAiIiB9CiAgICAgICAgcmV0dXJuICJwdWJsaWMgIgogICAgfQogICAgdmFyIGF0dHJpYnV0ZXM6IFN0cmluZyB7CiAgICAgICAgbGV0IHZhbHVlID0gSGVscGVycy5leHRyYWN0QXR0cmlidXRlcyhmcm9tOiBzZWxmLnZhcmlhYmxlLmF0dHJpYnV0ZXMpCiAgICAgICAgcmV0dXJuIHZhbHVlLmlzRW1wdHkgPyAiXChhY2Nlc3NNb2RpZmllcikiIDogIlwodmFsdWUpXG5cdFx0XChhY2Nlc3NNb2RpZmllcikiCiAgICB9CiAgICB2YXIgbm9TdHViRGVmaW5lZE1lc3NhZ2U6IFN0cmluZyB7IHJldHVybiAiXChzY29wZSkgLSBzdHViIHZhbHVlIGZvciBcKHZhcmlhYmxlLm5hbWUpIHdhcyBub3QgZGVmaW5lZCIgfQoKICAgIHZhciBnZXR0ZXI6IFN0cmluZyB7CiAgICAgICAgbGV0IHN0YXRpY01vZGlmaWVyID0gdmFyaWFibGUuaXNTdGF0aWMgPyAiXChzY29wZSkuIiA6ICIiCiAgICAgICAgbGV0IHJldHVyblZhbHVlID0gdmFyaWFibGUuaXNPcHRpb25hbCA/ICJvcHRpb25hbEdpdmVuR2V0dGVyVmFsdWUoLlwocHJvcGVydHlDYXNlR2V0TmFtZSksIFwiXChub1N0dWJEZWZpbmVkTWVzc2FnZSlcIikiIDogImdpdmVuR2V0dGVyVmFsdWUoLlwocHJvcGVydHlDYXNlR2V0TmFtZSksIFwiXChub1N0dWJEZWZpbmVkTWVzc2FnZSlcIikiCiAgICAgICAgcmV0dXJuICJcblx0XHRnZXQge1x0XChzdGF0aWNNb2RpZmllcilpbnZvY2F0aW9ucy5hcHBlbmQoLlwocHJvcGVydHlDYXNlR2V0TmFtZSkpOyByZXR1cm4gXChzdGF0aWNNb2RpZmllcilcKHByaXZhdGVQcm90b3R5cGVOYW1lKSA/PyBcKHJldHVyblZhbHVlKSB9IgogICAgfQogICAgdmFyIHNldHRlcjogU3RyaW5nIHsKICAgICAgICBsZXQgc3RhdGljTW9kaWZpZXIgPSB2YXJpYWJsZS5pc1N0YXRpYyA/ICJcKHNjb3BlKS4iIDogIiIKICAgICAgICBpZiByZWFkb25seSB7CiAgICAgICAgICAgIHJldHVybiAiIgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAiXG5cdFx0c2V0IHtcdFwoc3RhdGljTW9kaWZpZXIpaW52b2NhdGlvbnMuYXBwZW5kKC5cKHByb3BlcnR5Q2FzZVNldE5hbWUpKC52YWx1ZShuZXdWYWx1ZSkpKTsgXCh2YXJpYWJsZS5pc1N0YXRpYyA/ICJcKHNjb3BlKS4iIDogIiIpXChwcml2YXRlUHJvdG90eXBlTmFtZSkgPSBuZXdWYWx1ZSB9IgogICAgICAgIH0KICAgIH0KICAgIHZhciBwcm90b3R5cGU6IFN0cmluZyB7CiAgICAgICAgbGV0IHN0YXRpY01vZGlmaWVyID0gdmFyaWFibGUuaXNTdGF0aWMgPyAic3RhdGljICIgOiAiIgoKICAgICAgICByZXR1cm4gIlwoYXR0cmlidXRlcylcKHN0YXRpY01vZGlmaWVyKXZhciBcKHZhcmlhYmxlLm5hbWUpOiBcKHZhcmlhYmxlLnR5cGVOYW1lLm5hbWUpIHsiICsKICAgICAgICAgICAgIlwoZ2V0dGVyKSIgKwogICAgICAgICAgICAiXChzZXR0ZXIpIiArCiAgICAgICAgIlxuXHR9IgogICAgfQogICAgdmFyIGFzc2VydGlvbk5hbWU6IFN0cmluZyB7CiAgICAgICAgdmFyIHJlc3VsdCA9ICJjYXNlIC5cKHByb3BlcnR5Q2FzZUdldE5hbWUpOiByZXR1cm4gXCJbZ2V0XSAuXCh2YXJpYWJsZS5uYW1lKVwiIgogICAgICAgIGlmICFyZWFkb25seSB7CiAgICAgICAgICAgIHJlc3VsdCArPSAiXG5cdFx0XHRjYXNlIC5cKHByb3BlcnR5Q2FzZVNldE5hbWUpOiByZXR1cm4gXCJbc2V0XSAuXCh2YXJpYWJsZS5uYW1lKVwiIgogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0CiAgICB9CgogICAgdmFyIHByaXZhdGVQcm90b3R5cGU6IFN0cmluZyB7CiAgICAgICAgbGV0IHN0YXRpY01vZGlmaWVyID0gdmFyaWFibGUuaXNTdGF0aWMgPyAic3RhdGljICIgOiAiIgogICAgICAgIHZhciB0eXBlTmFtZSA9ICJcKHZhcmlhYmxlLnR5cGVOYW1lLnVud3JhcHBlZFR5cGVOYW1lKSIKICAgICAgICBsZXQgaXNXcmFwcGVkSW5CcmFja2V0cyA9IHR5cGVOYW1lLmhhc1ByZWZpeCgiKCIpICYmIHR5cGVOYW1lLmhhc1N1ZmZpeCgiKSIpCiAgICAgICAgaWYgIWlzV3JhcHBlZEluQnJhY2tldHMgewogICAgICAgICAgICB0eXBlTmFtZSA9ICIoXCh0eXBlTmFtZSkpIgogICAgICAgIH0KICAgICAgICByZXR1cm4gInByaXZhdGUgXChzdGF0aWNNb2RpZmllcil2YXIgXChwcml2YXRlUHJvdG90eXBlTmFtZSk6IFwodHlwZU5hbWUpPyIKICAgIH0KICAgIHZhciBuZXN0ZWRUeXBlOiBTdHJpbmcgeyByZXR1cm4gIlwoVHlwZVdyYXBwZXIodmFyaWFibGUudHlwZU5hbWUpLm5lc3RlZFBhcmFtZXRlcikiIH0KCiAgICBpbml0KF8gdmFyaWFibGU6IFNvdXJjZXJ5UnVudGltZS5WYXJpYWJsZSwgc2NvcGU6IFN0cmluZykgewogICAgICAgIHNlbGYudmFyaWFibGUgPSB2YXJpYWJsZQogICAgICAgIHNlbGYuc2NvcGUgPSBzY29wZQogICAgfQoKICAgIGZ1bmMgY29tcGFyZUNhc2VzKCkgLT4gU3RyaW5nIHsKICAgICAgICB2YXIgcmVzdWx0ID0gIHByb3BlcnR5Q2FzZUdldENvbXBhcmUoKQogICAgICAgIGlmICFyZWFkb25seSB7CiAgICAgICAgICAgIHJlc3VsdCArPSAiXG5cdFx0XHRcKHByb3BlcnR5Q2FzZVNldENvbXBhcmUoKSkiCiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQKICAgIH0KCiAgICBmdW5jIHByb3BlcnR5R2V0KCkgLT4gU3RyaW5nIHsKICAgICAgICBsZXQgc3RhdGljTW9kaWZpZXIgPSB2YXJpYWJsZS5pc1N0YXRpYyA/ICJTdGF0aWMiIDogIiIKICAgICAgICByZXR1cm4gInB1YmxpYyBzdGF0aWMgdmFyIFwodmFyaWFibGUubmFtZSk6IFwoc3RhdGljTW9kaWZpZXIpVmVyaWZ5IHsgcmV0dXJuIFwoc3RhdGljTW9kaWZpZXIpVmVyaWZ5KG1ldGhvZDogLlwocHJvcGVydHlDYXNlR2V0TmFtZSkpIH0iCiAgICB9CgogICAgZnVuYyBwcm9wZXJ0eVNldCgpIC0+IFN0cmluZyB7CiAgICAgICAgbGV0IHN0YXRpY01vZGlmaWVyID0gdmFyaWFibGUuaXNTdGF0aWMgPyAiU3RhdGljIiA6ICIiCiAgICAgICAgcmV0dXJuICJwdWJsaWMgc3RhdGljIGZ1bmMgXCh2YXJpYWJsZS5uYW1lKShzZXQgbmV3VmFsdWU6IFwobmVzdGVkVHlwZSkpIC0+IFwoc3RhdGljTW9kaWZpZXIpVmVyaWZ5IHsgcmV0dXJuIFwoc3RhdGljTW9kaWZpZXIpVmVyaWZ5KG1ldGhvZDogLlwocHJvcGVydHlDYXNlU2V0TmFtZSkobmV3VmFsdWUpKSB9IgogICAgfQoKICAgIHZhciBwcm9wZXJ0eUNhc2VHZXROYW1lOiBTdHJpbmcgeyByZXR1cm4gInBfXCh2YXJpYWJsZS5uYW1lKV9nZXQiLnJlcGxhY2luZ09jY3VycmVuY2VzKG9mOiAiYCIsIHdpdGg6ICIiKSB9CiAgICBmdW5jIHByb3BlcnR5Q2FzZUdldCgpIC0+IFN0cmluZyB7CiAgICAgICAgcmV0dXJuICJjYXNlIFwocHJvcGVydHlDYXNlR2V0TmFtZSkiCiAgICB9CiAgICBmdW5jIHByb3BlcnR5Q2FzZUdldENvbXBhcmUoKSAtPiBTdHJpbmcgewogICAgICAgIHJldHVybiAiY2FzZSAoLlwocHJvcGVydHlDYXNlR2V0TmFtZSksLlwocHJvcGVydHlDYXNlR2V0TmFtZSkpOiByZXR1cm4gTWF0Y2hlci5Db21wYXJpc29uUmVzdWx0Lm1hdGNoIgogICAgfQogICAgZnVuYyBwcm9wZXJ0eUNhc2VHZXRJbnRWYWx1ZSgpIC0+IFN0cmluZyB7CiAgICAgICAgcmV0dXJuICJjYXNlIC5cKHByb3BlcnR5Q2FzZUdldE5hbWUpOiByZXR1cm4gMCIKICAgIH0KCiAgICB2YXIgcHJvcGVydHlDYXNlU2V0TmFtZTogU3RyaW5nIHsgcmV0dXJuICJwX1wodmFyaWFibGUubmFtZSlfc2V0Ii5yZXBsYWNpbmdPY2N1cnJlbmNlcyhvZjogImAiLCB3aXRoOiAiIikgfQogICAgZnVuYyBwcm9wZXJ0eUNhc2VTZXQoKSAtPiBTdHJpbmcgewogICAgICAgIHJldHVybiAiY2FzZSBcKHByb3BlcnR5Q2FzZVNldE5hbWUpKFwobmVzdGVkVHlwZSkpIgogICAgfQogICAgZnVuYyBwcm9wZXJ0eUNhc2VTZXRDb21wYXJlKCkgLT4gU3RyaW5nIHsKICAgICAgICBsZXQgbGhzTmFtZSA9ICJsZWZ0IgogICAgICAgIGxldCByaHNOYW1lID0gInJpZ2h0IgogICAgICAgIGxldCBjb21hcHJpc29uID0gIk1hdGNoZXIuUGFyYW1ldGVyQ29tcGFyaXNvblJlc3VsdChcKG5lc3RlZFR5cGUpLmNvbXBhcmUobGhzOiBcKGxoc05hbWUpLCByaHM6IFwocmhzTmFtZSksIHdpdGg6IG1hdGNoZXIpLCBcKGxoc05hbWUpLCBcKHJoc05hbWUpLCBcIm5ld1ZhbHVlXCIpIgogICAgICAgIGxldCByZXN1bHQgPSAiTWF0Y2hlci5Db21wYXJpc29uUmVzdWx0KFtcKGNvbWFwcmlzb24pXSkiCiAgICAgICAgcmV0dXJuICJjYXNlICguXChwcm9wZXJ0eUNhc2VTZXROYW1lKShsZXQgbGVmdCksLlwocHJvcGVydHlDYXNlU2V0TmFtZSkobGV0IHJpZ2h0KSk6IHJldHVybiBcKHJlc3VsdCkiCiAgICB9CiAgICBmdW5jIHByb3BlcnR5Q2FzZVNldEludFZhbHVlKCkgLT4gU3RyaW5nIHsKICAgICAgICByZXR1cm4gImNhc2UgLlwocHJvcGVydHlDYXNlU2V0TmFtZSkobGV0IG5ld1ZhbHVlKTogcmV0dXJuIG5ld1ZhbHVlLmludFZhbHVlIgogICAgfQoKICAgIC8vIEdpdmVuCiAgICBmdW5jIGdpdmVuQ29uc3RydWN0b3JOYW1lKHByZWZpeDogU3RyaW5nID0gIiIpIC0+IFN0cmluZyB7CiAgICAgICAgcmV0dXJuICJcKGF0dHJpYnV0ZXMpc3RhdGljIGZ1bmMgXCh2YXJpYWJsZS5uYW1lKShnZXR0ZXIgZGVmYXVsdFZhbHVlOiBcKFR5cGVXcmFwcGVyKHZhcmlhYmxlLnR5cGVOYW1lKS5zdHJpcHBlZCkuLi4pIC0+IFwocHJlZml4KVByb3BlcnR5U3R1YiIKICAgIH0KCiAgICBmdW5jIGdpdmVuQ29uc3RydWN0b3IocHJlZml4OiBTdHJpbmcgPSAiIikgLT4gU3RyaW5nIHsKICAgICAgICByZXR1cm4gInJldHVybiBcKHByZWZpeClHaXZlbihtZXRob2Q6IC5cKHByb3BlcnR5Q2FzZUdldE5hbWUpLCBwcm9kdWN0czogZGVmYXVsdFZhbHVlLm1hcCh7IFN0dWJQcm9kdWN0LnJldHVybigkMCBhcyBBbnkpIH0pKSIKICAgIH0KfQpfJT4KPCUjID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IFNFVFVQIC0lPjwlXyAtJT4KPCVfIHZhciBhbGwgPSB0eXBlcy5hbGwKICAgIGFsbCArPSB0eXBlcy5wcm90b2NvbHMubWFwIHsgJDAgfQogICAgYWxsICs9IHR5cGVzLnByb3RvY29sQ29tcG9zaXRpb25zLm1hcCB7ICQwIH0KICAgIHZhciBtb2NrZWRDb3VudCA9IDAKLSU+Cgo8JV8gZm9yIHR5cGUgaW4gYWxsIHsgLSU+PCVfIC0lPgo8JV8gbGV0IGF1dG9Nb2NrYWJsZTogQm9vbCA9IHR5cGUuaW5oZXJpdGVkVHlwZXMuY29udGFpbnMoIkF1dG9Nb2NrYWJsZSIpIHx8IHR5cGUuYW5ub3RhdGlvbnNbIkF1dG9Nb2NrYWJsZSJdICE9IG5pbAogICAgbGV0IHByb3RvY29sVG9EZWNvcmF0ZSA9IHR5cGVzLnByb3RvY29scy5maXJzdCh3aGVyZTogeyAkMC5uYW1lID09ICh0eXBlLmFubm90YXRpb25zWyJtb2NrIl0gYXM/IFN0cmluZykgfSkKICAgIGxldCBpbmxpbmVNb2NrYWJsZSA9IHByb3RvY29sVG9EZWNvcmF0ZSAhPSBuaWwKICAgIGd1YXJkIGxldCBhUHJvdG9jb2wgPSBhdXRvTW9ja2FibGUgPyB0eXBlIDogcHJvdG9jb2xUb0RlY29yYXRlIGVsc2UgeyBjb250aW51ZSB9CiAgICBtb2NrZWRDb3VudCArPSAxCgogICAgbGV0IGFzc29jaWF0ZWRUeXBlczogW1N0cmluZ10/ID0gSGVscGVycy5leHRyYWN0QXNzb2NpYXRlZFR5cGVzKGZyb206IGFQcm90b2NvbCkKICAgIGxldCBhdHRyaWJ1dGVzOiBTdHJpbmcgPSBIZWxwZXJzLmV4dHJhY3RBdHRyaWJ1dGVzKGZyb206IHR5cGUuYXR0cmlidXRlcykKICAgIGxldCB0eXBlQWxpYXNlczogW1N0cmluZ10gPSBIZWxwZXJzLmV4dHJhY3RUeXBlYWxpYXNlcyhmcm9tOiBhUHJvdG9jb2wpCiAgICBsZXQgZ2VuZXJpY1R5cGVzTW9kaWZpZXI6IFN0cmluZyA9IEhlbHBlcnMuZXh0cmFjdEdlbmVyaWNUeXBlc01vZGlmaWVyKGFzc29jaWF0ZWRUeXBlcykKICAgIGxldCBnZW5lcmljVHlwZXNDb25zdHJhaW50czogU3RyaW5nID0gSGVscGVycy5leHRyYWN0R2VuZXJpY1R5cGVzQ29uc3RyYWludHMoYXNzb2NpYXRlZFR5cGVzKQogICAgbGV0IGFsbFN1YnNjcmlwdHMgPSBhUHJvdG9jb2wuYWxsU3Vic2NyaXB0cwogICAgbGV0IGFsbFZhcmlhYmxlcyA9IHVuaXF1ZXModmFyaWFibGVzOiBhUHJvdG9jb2wuYWxsVmFyaWFibGVzLmZpbHRlcih7ICEkMC5pc1N0YXRpYyB9KSkKICAgIGxldCBjb250YWluc1ZhcmlhYmxlcyA9ICFhbGxWYXJpYWJsZXMuaXNFbXB0eQogICAgbGV0IGFsbFN0YXRpY1ZhcmlhYmxlcyA9IHVuaXF1ZXModmFyaWFibGVzOiBhUHJvdG9jb2wuYWxsVmFyaWFibGVzLmZpbHRlcih7ICQwLmlzU3RhdGljIH0pKQogICAgbGV0IGNvbnRhaW5zU3RhdGljVmFyaWFibGVzID0gIWFsbFN0YXRpY1ZhcmlhYmxlcy5pc0VtcHR5CiAgICBsZXQgYWxsTWV0aG9kcyA9IHVuaXF1ZXMobWV0aG9kczogYVByb3RvY29sLmFsbE1ldGhvZHMuZmlsdGVyKHsgISQwLmlzU3RhdGljIHx8ICQwLmlzSW5pdGlhbGl6ZXIgfSkpCiAgICBsZXQgc2VsZkNvbnN0cmFpbmVkID0gYWxsTWV0aG9kcy5tYXAod3JhcE1ldGhvZCkuY29udGFpbnMod2hlcmU6IHsgJDAucmV0dXJuc0dlbmVyaWNDb25zdHJhaW5lZFRvU2VsZiB8fCAkMC5wYXJhbWV0ZXJzQ29udGFpbnNTZWxmIH0pCiAgICBsZXQgYWNjZXNzTW9kaWZpZXI6IFN0cmluZyA9IHNlbGZDb25zdHJhaW5lZCA/ICJwdWJsaWMgZmluYWwiIDogIm9wZW4iCiAgICBDdXJyZW50LmFjY2Vzc01vZGlmaWVyID0gYWNjZXNzTW9kaWZpZXIgLy8gVE9ETzogVGVtcG9yYXJ5IHdvcmthcm91bmQgZm9yIGFjY2VzcyBtb2RpZmllcnMKICAgIGxldCBpbmhlcml0RnJvbU5TT2JqZWN0ID0gdHlwZS5hbm5vdGF0aW9uc1siT2JqY1Byb3RvY29sIl0gIT0gbmlsIHx8IGF0dHJpYnV0ZXMuY29udGFpbnMoIkBvYmpjIikKICAgIGxldCBhbGxNZXRob2RzRm9yTWV0aG9kVHlwZSA9IHVuaXF1ZXNXaXRob3V0R2VuZXJpY0NvbnN0cmFpbnRzKG1ldGhvZHM6IGFQcm90b2NvbC5hbGxNZXRob2RzLmZpbHRlcih7ICEkMC5pc1N0YXRpYyB9KSkKICAgIGxldCBhbGxTdGF0aWNNZXRob2RzID0gdW5pcXVlcyhtZXRob2RzOiBhUHJvdG9jb2wuYWxsTWV0aG9kcy5maWx0ZXIoeyAkMC5pc1N0YXRpYyAmJiAhJDAuaXNJbml0aWFsaXplciB9KSkKICAgIGxldCBhbGxTdGF0aWNNZXRob2RzRm9yTWV0aG9kVHlwZSA9IHVuaXF1ZXNXaXRob3V0R2VuZXJpY0NvbnN0cmFpbnRzKG1ldGhvZHM6IGFQcm90b2NvbC5hbGxNZXRob2RzLmZpbHRlcih7ICQwLmlzU3RhdGljIH0pKQogICAgbGV0IGNvbmZvcm1zVG9TdGF0aWNNb2NrID0gIWFsbFN0YXRpY01ldGhvZHMuaXNFbXB0eSB8fCAhYWxsU3RhdGljVmFyaWFibGVzLmlzRW1wdHkKICAgIGxldCBjb25mb3Jtc1RvTW9jayA9ICFhbGxNZXRob2RzLmlzRW1wdHkgfHwgIWFsbFZhcmlhYmxlcy5pc0VtcHR5IC0lPjwlXyAtJT48JV8gLSU+CjwlXyBpZiBhdXRvTW9ja2FibGUgeyAtJT4KLy8gTUFSSzogLSA8JT0gdHlwZS5uYW1lICU+CjwlPSBhdHRyaWJ1dGVzICU+CjwlPSBhY2Nlc3NNb2RpZmllciAlPiBjbGFzcyA8JT0gdHlwZS5uYW1lICU+PCU9IG1vY2tUeXBlTmFtZSAlPjwlPSBnZW5lcmljVHlwZXNNb2RpZmllciAlPjo8JT0gaW5oZXJpdEZyb21OU09iamVjdCA/ICIgTlNPYmplY3QsIiA6ICIiICU+IDwlPSB0eXBlLm5hbWUgJT4sIE1vY2s8JT0gY29uZm9ybXNUb1N0YXRpY01vY2sgPyAiLCBTdGF0aWNNb2NrIiA6ICIiICU+PCU9IGdlbmVyaWNUeXBlc0NvbnN0cmFpbnRzICU+IHsKICAgIHB1YmxpYyBpbml0KHNlcXVlbmNpbmcgc2VxdWVuY2luZ1BvbGljeTogU2VxdWVuY2luZ1BvbGljeSA9IC5sYXN0V3JpdHRlblJlc29sdmVkRmlyc3QsIHN0dWJiaW5nIHN0dWJiaW5nUG9saWN5OiBTdHViYmluZ1BvbGljeSA9IC53cmFwLCBmaWxlOiBTdGF0aWNTdHJpbmcgPSAjZmlsZSwgbGluZTogVUludCA9ICNsaW5lKSB7CiAgICAgICAgU3dpZnR5TW9ja3lUZXN0T2JzZXJ2ZXIuc2V0dXAoKQogICAgICAgIHNlbGYuc2VxdWVuY2luZ1BvbGljeSA9IHNlcXVlbmNpbmdQb2xpY3kKICAgICAgICBzZWxmLnN0dWJiaW5nUG9saWN5ID0gc3R1YmJpbmdQb2xpY3kKICAgICAgICBzZWxmLmZpbGUgPSBmaWxlCiAgICAgICAgc2VsZi5saW5lID0gbGluZQogICAgfQoKPCVfIH0gZWxzZSB7IC0lPgovLyBzb3VyY2VyeTppbmxpbmU6YXV0bzo8JT0gdHlwZS5uYW1lICU+LmF1dG9Nb2NrZWQKPCVfIH0gLSU+CjwlIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBNQUlOIENMQVNTIC0lPjwlXyAtJT4KICA8JSMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gTU9DSyBJTlRFUk5BTFMgLSU+PCVfIC0lPgogICAgdmFyIG1hdGNoZXI6IE1hdGNoZXIgPSBNYXRjaGVyLmRlZmF1bHQKICAgIHZhciBzdHViYmluZ1BvbGljeTogU3R1YmJpbmdQb2xpY3kgPSAud3JhcAogICAgdmFyIHNlcXVlbmNpbmdQb2xpY3k6IFNlcXVlbmNpbmdQb2xpY3kgPSAubGFzdFdyaXR0ZW5SZXNvbHZlZEZpcnN0CgogICAgcHJpdmF0ZSB2YXIgcXVldWUgPSBEaXNwYXRjaFF1ZXVlKGxhYmVsOiAiY29tLnN3aWZ0eW1vY2t5Lmludm9jYXRpb25zIiwgcW9zOiAudXNlckludGVyYWN0aXZlKQogICAgcHJpdmF0ZSB2YXIgaW52b2NhdGlvbnM6IFtNZXRob2RUeXBlXSA9IFtdCiAgICBwcml2YXRlIHZhciBtZXRob2RSZXR1cm5WYWx1ZXM6IFtHaXZlbl0gPSBbXQogICAgcHJpdmF0ZSB2YXIgbWV0aG9kUGVyZm9ybVZhbHVlczogW1BlcmZvcm1dID0gW10KICAgIHByaXZhdGUgdmFyIGZpbGU6IFN0YXRpY1N0cmluZz8KICAgIHByaXZhdGUgdmFyIGxpbmU6IFVJbnQ/CgogICAgcHVibGljIHR5cGVhbGlhcyBQcm9wZXJ0eVN0dWIgPSBHaXZlbgogICAgcHVibGljIHR5cGVhbGlhcyBNZXRob2RTdHViID0gR2l2ZW4KICAgIHB1YmxpYyB0eXBlYWxpYXMgU3Vic2NyaXB0U3R1YiA9IEdpdmVuCiAgICA8JV8gZm9yIHR5cGVBbGlhcyBpbiB0eXBlQWxpYXNlcyB7IC0lPgogICAgcHVibGljIHR5cGVhbGlhcyA8JT0gdHlwZUFsaWFzICU+CiAgICA8JV8gfSAlPiA8JV8gLSU+CgogICAgLy8vIENvbnZlbmllbmNlIG1ldGhvZCAtIGNhbGwgc2V0dXBNb2NrKCkgdG8gZXh0ZW5kIGRlYnVnIGluZm9ybWF0aW9uIHdoZW4gZmFpbHVyZSBvY2N1cnMKICAgIHB1YmxpYyBmdW5jIHNldHVwTW9jayhmaWxlOiBTdGF0aWNTdHJpbmcgPSAjZmlsZSwgbGluZTogVUludCA9ICNsaW5lKSB7CiAgICAgICAgc2VsZi5maWxlID0gZmlsZQogICAgICAgIHNlbGYubGluZSA9IGxpbmUKICAgIH0KCiAgICAvLy8gQ2xlYXIgbW9jayBpbnRlcm5hbHMuIFlvdSBjYW4gc3BlY2lmeSB3aGF0IHRvIHJlc2V0IChpbnZvY2F0aW9ucyBha2EgdmVyaWZ5LCBnaXZlbnMgb3IgcGVyZm9ybXMpIG9yIGxlYXZlIGl0IGVtcHR5IHRvIGNsZWFyIGFsbCBtb2NrIGludGVybmFscwogICAgcHVibGljIGZ1bmMgcmVzZXRNb2NrKF8gc2NvcGVzOiBNb2NrU2NvcGUuLi4pIHsKICAgICAgICBsZXQgc2NvcGVzOiBbTW9ja1Njb3BlXSA9IHNjb3Blcy5pc0VtcHR5ID8gWy5pbnZvY2F0aW9uLCAuZ2l2ZW4sIC5wZXJmb3JtXSA6IHNjb3BlcwogICAgICAgIGlmIHNjb3Blcy5jb250YWlucyguaW52b2NhdGlvbikgeyBpbnZvY2F0aW9ucyA9IFtdIH0KICAgICAgICBpZiBzY29wZXMuY29udGFpbnMoLmdpdmVuKSB7IG1ldGhvZFJldHVyblZhbHVlcyA9IFtdIH0KICAgICAgICBpZiBzY29wZXMuY29udGFpbnMoLnBlcmZvcm0pIHsgbWV0aG9kUGVyZm9ybVZhbHVlcyA9IFtdIH0KICAgIH0KICAgIDwlXyAtJT4KICA8JSMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gU1RBVElDIE1PQ0sgSU5URVJOQUxTIC0lPjwlXyAtJT4KICAgIDwlXyBpZiBjb25mb3Jtc1RvU3RhdGljTW9jayB7IC0lPgogICAgc3RhdGljIHZhciBtYXRjaGVyOiBNYXRjaGVyID0gTWF0Y2hlci5kZWZhdWx0CiAgICBzdGF0aWMgdmFyIHN0dWJiaW5nUG9saWN5OiBTdHViYmluZ1BvbGljeSA9IC53cmFwCiAgICBzdGF0aWMgdmFyIHNlcXVlbmNpbmdQb2xpY3k6IFNlcXVlbmNpbmdQb2xpY3kgPSAubGFzdFdyaXR0ZW5SZXNvbHZlZEZpcnN0CiAgICBzdGF0aWMgcHJpdmF0ZSB2YXIgcXVldWUgPSBEaXNwYXRjaFF1ZXVlKGxhYmVsOiAiY29tLnN3aWZ0eW1vY2t5Lmludm9jYXRpb25zLnN0YXRpYyIsIHFvczogLnVzZXJJbnRlcmFjdGl2ZSkKICAgIHN0YXRpYyBwcml2YXRlIHZhciBpbnZvY2F0aW9uczogW1N0YXRpY01ldGhvZFR5cGVdID0gW10KICAgIHN0YXRpYyBwcml2YXRlIHZhciBtZXRob2RSZXR1cm5WYWx1ZXM6IFtTdGF0aWNHaXZlbl0gPSBbXQogICAgc3RhdGljIHByaXZhdGUgdmFyIG1ldGhvZFBlcmZvcm1WYWx1ZXM6IFtTdGF0aWNQZXJmb3JtXSA9IFtdCiAgICBwdWJsaWMgdHlwZWFsaWFzIFN0YXRpY1Byb3BlcnR5U3R1YiA9IFN0YXRpY0dpdmVuCiAgICBwdWJsaWMgdHlwZWFsaWFzIFN0YXRpY01ldGhvZFN0dWIgPSBTdGF0aWNHaXZlbgoKICAgIC8vLyBDbGVhciBtb2NrIGludGVybmFscy4gWW91IGNhbiBzcGVjaWZ5IHdoYXQgdG8gcmVzZXQgKGludm9jYXRpb25zIGFrYSB2ZXJpZnksIGdpdmVucyBvciBwZXJmb3Jtcykgb3IgbGVhdmUgaXQgZW1wdHkgdG8gY2xlYXIgYWxsIG1vY2sgaW50ZXJuYWxzCiAgICBwdWJsaWMgc3RhdGljIGZ1bmMgcmVzZXRNb2NrKF8gc2NvcGVzOiBNb2NrU2NvcGUuLi4pIHsKICAgICAgICBsZXQgc2NvcGVzOiBbTW9ja1Njb3BlXSA9IHNjb3Blcy5pc0VtcHR5ID8gWy5pbnZvY2F0aW9uLCAuZ2l2ZW4sIC5wZXJmb3JtXSA6IHNjb3BlcwogICAgICAgIGlmIHNjb3Blcy5jb250YWlucyguaW52b2NhdGlvbikgeyBpbnZvY2F0aW9ucyA9IFtdIH0KICAgICAgICBpZiBzY29wZXMuY29udGFpbnMoLmdpdmVuKSB7IG1ldGhvZFJldHVyblZhbHVlcyA9IFtdIH0KICAgICAgICBpZiBzY29wZXMuY29udGFpbnMoLnBlcmZvcm0pIHsgbWV0aG9kUGVyZm9ybVZhbHVlcyA9IFtdIH0KICAgIH0KICAgIDwlXyAgfSAtJT4KCiAgPCUjID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IFZBUklBQkxFUyAtJT48JV8gLSU+CiAgICA8JV8gZm9yIHZhcmlhYmxlIGluIGFsbFZhcmlhYmxlcyB7IC0lPgogICAgPCVfIGlmIGF1dG9Nb2NrYWJsZSB7IC0lPgogICAgPCU9IHN0dWJQcm9wZXJ0eSh2YXJpYWJsZSwiXCh0eXBlLm5hbWUpXChtb2NrVHlwZU5hbWUpIikgJT4KICAgIDwlXyB9IGVsc2UgeyAlPgogICAgPCU9IHN0dWJQcm9wZXJ0eSh2YXJpYWJsZSwiXCh0eXBlLm5hbWUpIikgJT4KICAgIDwlXyB9ICU+CiAgICA8JV8gfSAlPiA8JV8gLSU+CgogIDwlIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBTVEFUSUMgVkFSSUFCTEVTIC0lPjwlXyAtJT4KICAgIDwlXyBmb3IgdmFyaWFibGUgaW4gYWxsU3RhdGljVmFyaWFibGVzIHsgLSU+CiAgICA8JV8gaWYgYXV0b01vY2thYmxlIHsgLSU+CiAgICA8JT0gc3R1YlByb3BlcnR5KHZhcmlhYmxlLCJcKHR5cGUubmFtZSlcKG1vY2tUeXBlTmFtZSkiKSAlPgogICAgPCVfIH0gZWxzZSB7ICU+CiAgICA8JT0gc3R1YlByb3BlcnR5KHZhcmlhYmxlLCJcKHR5cGUubmFtZSkiKSAlPgogICAgPCVfIH0gJT4KICAgIDwlXyB9ICU+IDwlXyAtJT4KCiAgPCUjID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IE1FVEhPRCBSRUdJU1RSQVRJT05TIC0lPjwlXyAtJT4KICAgIDwlXyBNZXRob2RXcmFwcGVyLmNsZWFyKCkgLSU+CiAgICA8JV8gU3Vic2NyaXB0V3JhcHBlci5jbGVhcigpIC0lPgogICAgPCVfIGlmIGF1dG9Nb2NrYWJsZSB7IC0lPgogICAgPCVfIEN1cnJlbnQuc2VsZlR5cGUgPSAiXCh0eXBlLm5hbWUpXChtb2NrVHlwZU5hbWUpXChnZW5lcmljVHlwZXNNb2RpZmllcikiIC0lPgogICAgPCVfIH0gZWxzZSB7ICU+CiAgICA8JV8gQ3VycmVudC5zZWxmVHlwZSA9ICJcKHR5cGUubmFtZSlcKG1vY2tUeXBlTmFtZSlcKGdlbmVyaWNUeXBlc01vZGlmaWVyKSIgLSU+CiAgICA8JV8gfSAlPgogICAgPCVfIGxldCB3cmFwcGVkU3Vic2NyaXB0cyA9IGFsbFN1YnNjcmlwdHMubWFwKHdyYXBTdWJzY3JpcHQpIC0lPgogICAgPCVfIGxldCB3cmFwcGVkTWV0aG9kcyA9IGFsbE1ldGhvZHMubWFwKHdyYXBNZXRob2QpLmZpbHRlcih7ICQwLndyYXBwZWRJbk1ldGhvZFR5cGUoKSB9KSAtJT4KICAgIDwlXyBsZXQgd3JhcHBlZFZhcmlhYmxlcyA9IGFsbFZhcmlhYmxlcy5tYXAoanVzdFdyYXApIC0lPgogICAgPCVfIGxldCB3cmFwcGVkTWV0aG9kc0Zvck1ldGhvZFR5cGUgPSBhbGxNZXRob2RzRm9yTWV0aG9kVHlwZS5tYXAod3JhcE1ldGhvZCkuZmlsdGVyKHsgJDAud3JhcHBlZEluTWV0aG9kVHlwZSgpIH0pIC0lPgogICAgPCVfIGxldCB3cmFwcGVkSW5pdGlhbGl6ZXJzID0gYWxsTWV0aG9kcy5tYXAod3JhcE1ldGhvZCkuZmlsdGVyKHsgJDAubWV0aG9kLmlzSW5pdGlhbGl6ZXIgfSkgLSU+CiAgICA8JV8gbGV0IHdyYXBwZWRTdGF0aWNNZXRob2RzID0gYWxsU3RhdGljTWV0aG9kcy5tYXAod3JhcE1ldGhvZCkuZmlsdGVyKHsgJDAud3JhcHBlZEluTWV0aG9kVHlwZSgpIH0pIC0lPgogICAgPCVfIGxldCB3cmFwcGVkU3RhdGljVmFyaWFibGVzID0gYWxsU3RhdGljVmFyaWFibGVzLm1hcChqdXN0V3JhcCkgLSU+CiAgICA8JV8gbGV0IHdyYXBwZWRTdGF0aWNNZXRob2RzRm9yTWV0aG9kVHlwZSA9IGFsbFN0YXRpY01ldGhvZHNGb3JNZXRob2RUeXBlLm1hcCh3cmFwTWV0aG9kKS5maWx0ZXIoeyAkMC53cmFwcGVkSW5NZXRob2RUeXBlKCkgfSkgLSU+CiAgICA8JV8gZm9yIHZhcmlhYmxlIGluIGFsbFZhcmlhYmxlcyB7IHByb3BlcnR5UmVnaXN0ZXIodmFyaWFibGUpIH0gLSU+CiAgICA8JV8gZm9yIHZhcmlhYmxlIGluIGFsbFN0YXRpY1ZhcmlhYmxlcyB7IHByb3BlcnR5UmVnaXN0ZXIodmFyaWFibGUpIH0gLSU+CiAgICA8JV8gZm9yIG1ldGhvZCBpbiB3cmFwcGVkTWV0aG9kcyB7IG1ldGhvZC5yZWdpc3RlcigpIH0gLSU+CiAgICA8JV8gZm9yIHdyYXBwZWQgaW4gd3JhcHBlZFN1YnNjcmlwdHMgeyB3cmFwcGVkLnJlZ2lzdGVyKCkgfSAtJT4KICAgIDwlXyBmb3IgbWV0aG9kIGluIHdyYXBwZWRTdGF0aWNNZXRob2RzIHsgbWV0aG9kLnJlZ2lzdGVyKCkgfSAtJT48JV8gLSU+CiAgICA8JV8gbGV0IHZhcmlhYmxlQ2FzZXNDb3VudDogSW50ID0gd3JhcHBlZFZhcmlhYmxlcy5yZWR1Y2UoMCkgeyByZXR1cm4gJDAgKyAkMS5jYXNlc0NvdW50IH0gLSU+PCVfIC0lPgogICAgPCVfIGxldCBzdWJzY3JpcHRzQ2FzZXNDb3VudDogSW50ID0gd3JhcHBlZFN1YnNjcmlwdHMucmVkdWNlKDApIHsgcmV0dXJuICQwICsgJDEuY2FzZXNDb3VudCB9IC0lPjwlXyAtJT4KICAgIDwlXyBsZXQgc3RhdGljVmFyaWFibGVDYXNlc0NvdW50OiBJbnQgPSB3cmFwcGVkU3RhdGljVmFyaWFibGVzLnJlZHVjZSgwKSB7IHJldHVybiAkMCArICQxLmNhc2VzQ291bnQgfSAtJT48JV8gLSU+CgogIDwlIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBTVEFUSUMgU1RVQlMgLSU+PCVfIC0lPgogICAgPCVfIGZvciBtZXRob2QgaW4gd3JhcHBlZFN0YXRpY01ldGhvZHMgeyAtJT4KICAgIDwlPSBtZXRob2QuZnVuY3Rpb25Qcm90b3R5cGUgXyU+IHsKICAgICAgICA8JT0gbWV0aG9kLnN0dWJCb2R5KCkgXyU+CiAgICB9CgogICAgPCVfIH0gJT48JV8gLSU+CiAgICA8JV8gLSU+CiAgPCUjID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IElOSVRJQUxJWkVSUyAtJT48JV8gLSU+CiAgICA8JV8gZm9yIG1ldGhvZCBpbiB3cmFwcGVkSW5pdGlhbGl6ZXJzIHsgLSU+CiAgICA8JT0gbWV0aG9kLmZ1bmN0aW9uUHJvdG90eXBlIF8lPiB7IH0KCiAgICA8JV8gfSAtJT48JV8gLSU+CiAgICA8JV8gLSU+PCVfIC0lPgogIDwlIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBTVFVCUyAtJT48JV8gLSU+CiAgICA8JV8gZm9yIG1ldGhvZCBpbiB3cmFwcGVkTWV0aG9kcyB7IC0lPgogICAgPCU9IG1ldGhvZC5mdW5jdGlvblByb3RvdHlwZSBfJT4gewogICAgICAgIDwlPSBtZXRob2Quc3R1YkJvZHkoKSBfJT4KICAgIH0KCiAgICA8JV8gfSAtJT4KICAgIDwlXyBmb3Igd3JhcHBlZCBpbiB3cmFwcGVkU3Vic2NyaXB0cyB7IC0lPgogICAgPCU9IHdyYXBwZWQuc3Vic2NyaXB0Q2FsbCgpIF8lPgoKICAgIDwlXyB9IC0lPgogIDwlIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBTVEFUSUMgTUVUSE9EIFRZUEUgLSU+PCVfIC0lPgogICAgPCVfIGlmIGNvbmZvcm1zVG9TdGF0aWNNb2NrIHsgLSU+CiAgICBmaWxlcHJpdmF0ZSBlbnVtIFN0YXRpY01ldGhvZFR5cGUgewogICAgPCVfIGZvciBtZXRob2QgaW4gd3JhcHBlZFN0YXRpY01ldGhvZHNGb3JNZXRob2RUeXBlIHsgLSU+CiAgICAgICAgPCU9IG1ldGhvZC5tZXRob2RUeXBlRGVjbGFyYXRpb25XaXRoUGFyYW1ldGVycygpIF8lPgogICAgPCVfICB9ICU+IDwlXyBmb3IgdmFyaWFibGUgaW4gYWxsU3RhdGljVmFyaWFibGVzIHsgLSU+CiAgICAgICAgPCU9IHByb3BlcnR5TWV0aG9kVHlwZXModmFyaWFibGUpICU+CiAgICA8JV8gfSAlPiA8JV8gJT4KICAgIDwlXyAtJT4KICAgICAgICBzdGF0aWMgZnVuYyBjb21wYXJlUGFyYW1ldGVycyhsaHM6IFN0YXRpY01ldGhvZFR5cGUsIHJoczogU3RhdGljTWV0aG9kVHlwZSwgbWF0Y2hlcjogTWF0Y2hlcikgLT4gTWF0Y2hlci5Db21wYXJpc29uUmVzdWx0IHsKICAgICAgICAgICAgc3dpdGNoIChsaHMsIHJocykgeyA8JV8gZm9yIG1ldGhvZCBpbiB3cmFwcGVkU3RhdGljTWV0aG9kc0Zvck1ldGhvZFR5cGUgeyAlPgogICAgICAgICAgICA8JT0gbWV0aG9kLmVxdWFsQ2FzZXMoKSAlPgogICAgICAgICAgICA8JV8gfSAlPiA8JV8gZm9yIHZhcmlhYmxlIGluIHdyYXBwZWRTdGF0aWNWYXJpYWJsZXMgeyAtJT4KICAgICAgICAgICAgPCU9IHZhcmlhYmxlLmNvbXBhcmVDYXNlcygpICU+CiAgICAgICAgICAgIDwlXyB9ICU+IDwlXyAtJT4gPCVfIGlmIHdyYXBwZWRTdGF0aWNNZXRob2RzLmNvdW50ICsgc3RhdGljVmFyaWFibGVDYXNlc0NvdW50ID4gMSB7IC0lPgogICAgICAgICAgICBkZWZhdWx0OiByZXR1cm4gLm5vbmUKICAgICAgICAgICAgPCVfIH0gLSU+CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICA8JV8gJT4KICAgICAgICBmdW5jIGludFZhbHVlKCkgLT4gSW50IHsKICAgICAgICAgICAgc3dpdGNoIHNlbGYgeyA8JV8gZm9yIG1ldGhvZCBpbiB3cmFwcGVkU3RhdGljTWV0aG9kc0Zvck1ldGhvZFR5cGUgeyAlPgogICAgICAgICAgICAgICAgPCU9IG1ldGhvZC5pbnRWYWx1ZUNhc2UgLSU+PCUgfSAlPgogICAgICAgICAgICAgICAgPCVfIGZvciB2YXJpYWJsZSBpbiBhbGxTdGF0aWNWYXJpYWJsZXMgeyAtJT4KICAgICAgICAgICAgICAgIDwlPSBwcm9wZXJ0eU1ldGhvZFR5cGVzSW50VmFsdWUodmFyaWFibGUpICU+CiAgICAgICAgICAgICAgICA8JV8gfSAlPiA8JV8gLSU+CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZnVuYyBhc3NlcnRpb25OYW1lKCkgLT4gU3RyaW5nIHsKICAgICAgICAgICAgc3dpdGNoIHNlbGYgeyA8JV8gZm9yIG1ldGhvZCBpbiB3cmFwcGVkU3RhdGljTWV0aG9kc0Zvck1ldGhvZFR5cGUgeyAlPgogICAgICAgICAgICA8JT0gbWV0aG9kLmFzc2VydGlvbk5hbWUgLSU+PCUgfSAlPgogICAgICAgICAgICA8JV8gZm9yIHZhcmlhYmxlIGluIHdyYXBwZWRTdGF0aWNWYXJpYWJsZXMgeyAtJT4KICAgICAgICAgICAgPCU9IHZhcmlhYmxlLmFzc2VydGlvbk5hbWUgJT4KICAgICAgICAgICAgPCVfIH0gJT4KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBvcGVuIGNsYXNzIFN0YXRpY0dpdmVuOiBTdHViYmVkTWV0aG9kIHsKICAgICAgICBmaWxlcHJpdmF0ZSB2YXIgbWV0aG9kOiBTdGF0aWNNZXRob2RUeXBlCgogICAgICAgIHByaXZhdGUgaW5pdChtZXRob2Q6IFN0YXRpY01ldGhvZFR5cGUsIHByb2R1Y3RzOiBbU3R1YlByb2R1Y3RdKSB7CiAgICAgICAgICAgIHNlbGYubWV0aG9kID0gbWV0aG9kCiAgICAgICAgICAgIHN1cGVyLmluaXQocHJvZHVjdHMpCiAgICAgICAgfQoKICAgICAgICA8JV8gZm9yIHZhcmlhYmxlIGluIGFsbFN0YXRpY1ZhcmlhYmxlcyB7IC0lPgogICAgICAgIDwlPSB3cmFwUHJvcGVydHkodmFyaWFibGUpLmdpdmVuQ29uc3RydWN0b3JOYW1lKHByZWZpeDogIlN0YXRpYyIpIC0lPiB7CiAgICAgICAgICAgIDwlPSB3cmFwUHJvcGVydHkodmFyaWFibGUpLmdpdmVuQ29uc3RydWN0b3IocHJlZml4OiAiU3RhdGljIikgXyU+CiAgICAgICAgfQogICAgICAgIDwlXyB9ICU+IDwlXyAlPgogICAgICAgIDwlXyBmb3IgbWV0aG9kIGluIHdyYXBwZWRTdGF0aWNNZXRob2RzRm9yTWV0aG9kVHlwZS5maWx0ZXIoeyAhJDAubWV0aG9kLnJldHVyblR5cGVOYW1lLmlzVm9pZCAmJiAhJDAubWV0aG9kLmlzSW5pdGlhbGl6ZXIgfSkgeyAtJT4KICAgICAgICA8JT0gbWV0aG9kLmdpdmVuQ29uc3RydWN0b3JOYW1lKHByZWZpeDogIlN0YXRpYyIpIC0lPiB7CiAgICAgICAgICAgIDwlPSBtZXRob2QuZ2l2ZW5Db25zdHJ1Y3RvcihwcmVmaXg6ICJTdGF0aWMiKSBfJT4KICAgICAgICB9CiAgICAgICAgPCVfIH0gLSU+CiAgICAgICAgPCVfIGZvciBtZXRob2QgaW4gd3JhcHBlZFN0YXRpY01ldGhvZHNGb3JNZXRob2RUeXBlLmZpbHRlcih7ICEkMC5tZXRob2QudGhyb3dzICYmICEkMC5tZXRob2QucmV0aHJvd3MgJiYgISQwLm1ldGhvZC5yZXR1cm5UeXBlTmFtZS5pc1ZvaWQgJiYgISQwLm1ldGhvZC5pc0luaXRpYWxpemVyIH0pIHsgLSU+CiAgICAgICAgPCU9IG1ldGhvZC5naXZlblByb2R1Y2VDb25zdHJ1Y3Rvck5hbWUocHJlZml4OiAiU3RhdGljIikgLSU+IHsKICAgICAgICAgICAgPCU9IG1ldGhvZC5naXZlblByb2R1Y2VDb25zdHJ1Y3RvcihwcmVmaXg6ICJTdGF0aWMiKSBfJT4KICAgICAgICB9CiAgICAgICAgPCVfIH0gLSU+CiAgICAgICAgPCVfIGZvciBtZXRob2QgaW4gd3JhcHBlZFN0YXRpY01ldGhvZHNGb3JNZXRob2RUeXBlLmZpbHRlcih7ICgkMC5tZXRob2QudGhyb3dzIHx8ICQwLm1ldGhvZC5yZXRocm93cykgJiYgISQwLm1ldGhvZC5pc0luaXRpYWxpemVyIH0pIHsgLSU+CiAgICAgICAgPCU9IG1ldGhvZC5naXZlbkNvbnN0cnVjdG9yTmFtZVRocm93cyhwcmVmaXg6ICJTdGF0aWMiKSAtJT4gewogICAgICAgICAgICA8JT0gbWV0aG9kLmdpdmVuQ29uc3RydWN0b3JUaHJvd3MocHJlZml4OiAiU3RhdGljIikgXyU+CiAgICAgICAgfQogICAgICAgIDwlPSBtZXRob2QuZ2l2ZW5Qcm9kdWNlQ29uc3RydWN0b3JOYW1lVGhyb3dzKHByZWZpeDogIlN0YXRpYyIpIC0lPiB7CiAgICAgICAgICAgIDwlPSBtZXRob2QuZ2l2ZW5Qcm9kdWNlQ29uc3RydWN0b3JUaHJvd3MocHJlZml4OiAiU3RhdGljIikgXyU+CiAgICAgICAgfQogICAgICAgIDwlXyB9ICU+IDwlXyAtJT4KICAgIH0KCiAgICBwdWJsaWMgc3RydWN0IFN0YXRpY1ZlcmlmeSB7CiAgICAgICAgZmlsZXByaXZhdGUgdmFyIG1ldGhvZDogU3RhdGljTWV0aG9kVHlwZQoKICAgICAgICA8JV8gZm9yIG1ldGhvZCBpbiB3cmFwcGVkU3RhdGljTWV0aG9kc0Zvck1ldGhvZFR5cGUgeyAtJT4KICAgICAgICA8JT0gbWV0aG9kLnZlcmlmaWNhdGlvblByb3h5Q29uc3RydWN0b3JOYW1lKHByZWZpeDogIlN0YXRpYyIpIC0lPiB7IDwlPSBtZXRob2QudmVyaWZpY2F0aW9uUHJveHlDb25zdHJ1Y3RvcihwcmVmaXg6ICJTdGF0aWMiKSBfJT4gfQogICAgICAgIDwlXyB9ICU+IDwlXyAtJT4KICAgICAgICA8JV8gZm9yIHZhcmlhYmxlIGluIGFsbFN0YXRpY1ZhcmlhYmxlcyB7IC0lPgogICAgICAgIDwlPSBwcm9wZXJ0eVR5cGVzKHZhcmlhYmxlKSAlPgogICAgICAgIDwlXyB9ICU+IDwlXyAtJT4KICAgIH0KCiAgICBwdWJsaWMgc3RydWN0IFN0YXRpY1BlcmZvcm0gewogICAgICAgIGZpbGVwcml2YXRlIHZhciBtZXRob2Q6IFN0YXRpY01ldGhvZFR5cGUKICAgICAgICB2YXIgcGVyZm9ybXM6IEFueQoKICAgICAgICA8JV8gZm9yIG1ldGhvZCBpbiB3cmFwcGVkU3RhdGljTWV0aG9kc0Zvck1ldGhvZFR5cGUgeyAtJT4KICAgICAgICA8JT0gbWV0aG9kLnBlcmZvcm1Qcm94eUNvbnN0cnVjdG9yTmFtZShwcmVmaXg6ICJTdGF0aWMiKSAtJT4gewogICAgICAgICAgICA8JT0gbWV0aG9kLnBlcmZvcm1Qcm94eUNvbnN0cnVjdG9yKHByZWZpeDogIlN0YXRpYyIpIF8lPgogICAgICAgIH0KICAgICAgICA8JV8gfSAlPiA8JV8gLSU+CiAgICB9CgogICAgPCUgfSAtJT4KICA8JSMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gTUVUSE9EIFRZUEUgLSU+PCVfIC0lPgogICAgPCVfIGlmICF3cmFwcGVkTWV0aG9kcy5pc0VtcHR5IHx8ICFhbGxWYXJpYWJsZXMuaXNFbXB0eSB8fCAhYWxsU3Vic2NyaXB0cy5pc0VtcHR5IHsgLSU+CgogICAgZmlsZXByaXZhdGUgZW51bSBNZXRob2RUeXBlIHsKICAgIDwlXyBmb3IgbWV0aG9kIGluIHdyYXBwZWRNZXRob2RzRm9yTWV0aG9kVHlwZSB7IC0lPgogICAgICAgIDwlPSBtZXRob2QubWV0aG9kVHlwZURlY2xhcmF0aW9uV2l0aFBhcmFtZXRlcnMoKSBfJT4KICAgIDwlXyAgfSAtJT4gPCVfIGZvciB2YXJpYWJsZSBpbiBhbGxWYXJpYWJsZXMgeyAtJT4KICAgICAgICA8JT0gcHJvcGVydHlNZXRob2RUeXBlcyh2YXJpYWJsZSkgJT4KICAgIDwlXyB9ICU+IDwlXyAlPiA8JV8gZm9yIHdyYXBwZWQgaW4gd3JhcHBlZFN1YnNjcmlwdHMgeyAtJT4KICAgICAgICA8JT0gd3JhcHBlZC5zdWJzY3JpcHRDYXNlcygpIF8lPgogICAgPCVfIH0gJT4gPCVfICU+CiAgICA8JV8gLSU+CiAgICAgICAgc3RhdGljIGZ1bmMgY29tcGFyZVBhcmFtZXRlcnMobGhzOiBNZXRob2RUeXBlLCByaHM6IE1ldGhvZFR5cGUsIG1hdGNoZXI6IE1hdGNoZXIpIC0+IE1hdGNoZXIuQ29tcGFyaXNvblJlc3VsdCB7CiAgICAgICAgICAgIHN3aXRjaCAobGhzLCByaHMpIHsgPCVfIGZvciBtZXRob2QgaW4gd3JhcHBlZE1ldGhvZHNGb3JNZXRob2RUeXBlIHsgJT4KICAgICAgICAgICAgPCU9IG1ldGhvZC5lcXVhbENhc2VzKCkgJT4KICAgICAgICAgICAgPCVfIH0gJT4gPCVfIGZvciB2YXJpYWJsZSBpbiB3cmFwcGVkVmFyaWFibGVzIHsgLSU+CiAgICAgICAgICAgIDwlPSB2YXJpYWJsZS5jb21wYXJlQ2FzZXMoKSAlPgogICAgICAgICAgICA8JV8gfSAlPiA8JV8gLSU+IDwlXyBmb3Igd3JhcHBlZCBpbiB3cmFwcGVkU3Vic2NyaXB0cyB7IC0lPgogICAgICAgICAgICA8JT0gd3JhcHBlZC5lcXVhbENhc2VzKCkgJT4KICAgICAgICAgICAgPCVfIH0gJT4gPCVfIGlmIHdyYXBwZWRNZXRob2RzLmNvdW50ICsgdmFyaWFibGVDYXNlc0NvdW50ICsgc3Vic2NyaXB0c0Nhc2VzQ291bnQgPiAxIHsgLSU+CiAgICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiAubm9uZQogICAgICAgICAgICA8JV8gfSAtJT4KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIDwlXyAlPgogICAgICAgIGZ1bmMgaW50VmFsdWUoKSAtPiBJbnQgewogICAgICAgICAgICBzd2l0Y2ggc2VsZiB7IDwlXyBmb3IgbWV0aG9kIGluIHdyYXBwZWRNZXRob2RzRm9yTWV0aG9kVHlwZSB7ICU+CiAgICAgICAgICAgIDwlPSBtZXRob2QuaW50VmFsdWVDYXNlIC0lPjwlIH0gJT4KICAgICAgICAgICAgPCVfIGZvciB2YXJpYWJsZSBpbiBhbGxWYXJpYWJsZXMgeyAtJT4KICAgICAgICAgICAgPCU9IHByb3BlcnR5TWV0aG9kVHlwZXNJbnRWYWx1ZSh2YXJpYWJsZSkgJT4KICAgICAgICAgICAgPCVfIH0gJT4gPCVfIGZvciB3cmFwcGVkIGluIHdyYXBwZWRTdWJzY3JpcHRzIHsgLSU+CiAgICAgICAgICAgIDwlPSB3cmFwcGVkLmludFZhbHVlQ2FzZSgpICU+CiAgICAgICAgICAgIDwlXyB9IC0lPgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZ1bmMgYXNzZXJ0aW9uTmFtZSgpIC0+IFN0cmluZyB7CiAgICAgICAgICAgIHN3aXRjaCBzZWxmIHsgPCVfIGZvciBtZXRob2QgaW4gd3JhcHBlZE1ldGhvZHNGb3JNZXRob2RUeXBlIHsgJT4KICAgICAgICAgICAgPCU9IG1ldGhvZC5hc3NlcnRpb25OYW1lIC0lPjwlIH0gJT4KICAgICAgICAgICAgPCVfIGZvciB2YXJpYWJsZSBpbiB3cmFwcGVkVmFyaWFibGVzIHsgLSU+CiAgICAgICAgICAgIDwlPSB2YXJpYWJsZS5hc3NlcnRpb25OYW1lICU+CiAgICAgICAgICAgIDwlXyB9ICU+IDwlXyBmb3Igd3JhcHBlZCBpbiB3cmFwcGVkU3Vic2NyaXB0cyB7IC0lPgogICAgICAgICAgICA8JT0gd3JhcHBlZC5hc3NlcnRpb25OYW1lICU+CiAgICAgICAgICAgIDwlXyB9IC0lPgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgPCVfIH0gZWxzZSB7ICU+CiAgICBmaWxlcHJpdmF0ZSBzdHJ1Y3QgTWV0aG9kVHlwZSB7CiAgICAgICAgc3RhdGljIGZ1bmMgY29tcGFyZVBhcmFtZXRlcnMobGhzOiBNZXRob2RUeXBlLCByaHM6IE1ldGhvZFR5cGUsIG1hdGNoZXI6IE1hdGNoZXIpIC0+IE1hdGNoZXIuQ29tcGFyaXNvblJlc3VsdCB7IHJldHVybiAubWF0Y2ggfQogICAgICAgIGZ1bmMgaW50VmFsdWUoKSAtPiBJbnQgeyByZXR1cm4gMCB9CiAgICAgICAgZnVuYyBhc3NlcnRpb25OYW1lKCkgLT4gU3RyaW5nIHsgcmV0dXJuICIiIH0KICAgIH0KICAgIDwlXyB9IC0lPjwlXyAtJT4KCiAgICBvcGVuIGNsYXNzIEdpdmVuOiBTdHViYmVkTWV0aG9kIHsKICAgICAgICBmaWxlcHJpdmF0ZSB2YXIgbWV0aG9kOiBNZXRob2RUeXBlCgogICAgICAgIHByaXZhdGUgaW5pdChtZXRob2Q6IE1ldGhvZFR5cGUsIHByb2R1Y3RzOiBbU3R1YlByb2R1Y3RdKSB7CiAgICAgICAgICAgIHNlbGYubWV0aG9kID0gbWV0aG9kCiAgICAgICAgICAgIHN1cGVyLmluaXQocHJvZHVjdHMpCiAgICAgICAgfQoKICAgICAgICA8JV8gZm9yIHZhcmlhYmxlIGluIGFsbFZhcmlhYmxlcyB7IC0lPgogICAgICAgIDwlPSB3cmFwUHJvcGVydHkodmFyaWFibGUpLmdpdmVuQ29uc3RydWN0b3JOYW1lKCkgLSU+IHsKICAgICAgICAgICAgPCU9IHdyYXBQcm9wZXJ0eSh2YXJpYWJsZSkuZ2l2ZW5Db25zdHJ1Y3RvcigpIF8lPgogICAgICAgIH0KICAgICAgICA8JV8gfSAlPiA8JV8gJT4KICAgICAgICA8JV8gZm9yIG1ldGhvZCBpbiB3cmFwcGVkTWV0aG9kc0Zvck1ldGhvZFR5cGUuZmlsdGVyKHsgISQwLm1ldGhvZC5yZXR1cm5UeXBlTmFtZS5pc1ZvaWQgJiYgISQwLm1ldGhvZC5pc0luaXRpYWxpemVyIH0pIHsgLSU+CiAgICAgICAgPCU9IG1ldGhvZC5naXZlbkNvbnN0cnVjdG9yTmFtZSgpIC0lPiB7CiAgICAgICAgICAgIDwlPSBtZXRob2QuZ2l2ZW5Db25zdHJ1Y3RvcigpIF8lPgogICAgICAgIH0KICAgICAgICA8JV8gfSAtJT4KICAgICAgICA8JV8gZm9yIG1ldGhvZCBpbiB3cmFwcGVkTWV0aG9kc0Zvck1ldGhvZFR5cGUuZmlsdGVyKHsgISQwLm1ldGhvZC50aHJvd3MgJiYgISQwLm1ldGhvZC5yZXRocm93cyAmJiAhJDAubWV0aG9kLnJldHVyblR5cGVOYW1lLmlzVm9pZCAmJiAhJDAubWV0aG9kLmlzSW5pdGlhbGl6ZXIgfSkgeyAtJT4KICAgICAgICA8JT0gbWV0aG9kLmdpdmVuUHJvZHVjZUNvbnN0cnVjdG9yTmFtZSgpIC0lPiB7CiAgICAgICAgICAgIDwlPSBtZXRob2QuZ2l2ZW5Qcm9kdWNlQ29uc3RydWN0b3IoKSBfJT4KICAgICAgICB9CiAgICAgICAgPCVfIH0gLSU+CiAgICAgICAgPCVfIGZvciB3cmFwcGVkIGluIHdyYXBwZWRTdWJzY3JpcHRzIHsgLSU+CiAgICAgICAgPCU9IHdyYXBwZWQuZ2l2ZW5Db25zdHJ1Y3Rvck5hbWUoKSAtJT4gewogICAgICAgICAgICA8JT0gd3JhcHBlZC5naXZlbkNvbnN0cnVjdG9yKCkgXyU+CiAgICAgICAgfQogICAgICAgIDwlXyB9IC0lPgogICAgICAgIDwlXyBmb3IgbWV0aG9kIGluIHdyYXBwZWRNZXRob2RzRm9yTWV0aG9kVHlwZS5maWx0ZXIoeyAoJDAubWV0aG9kLnRocm93cyB8fCAkMC5tZXRob2QucmV0aHJvd3MpICYmICEkMC5tZXRob2QuaXNJbml0aWFsaXplciB9KSB7IC0lPgogICAgICAgIDwlPSBtZXRob2QuZ2l2ZW5Db25zdHJ1Y3Rvck5hbWVUaHJvd3MoKSAtJT4gewogICAgICAgICAgICA8JT0gbWV0aG9kLmdpdmVuQ29uc3RydWN0b3JUaHJvd3MoKSBfJT4KICAgICAgICB9CiAgICAgICAgPCU9IG1ldGhvZC5naXZlblByb2R1Y2VDb25zdHJ1Y3Rvck5hbWVUaHJvd3MoKSAtJT4gewogICAgICAgICAgICA8JT0gbWV0aG9kLmdpdmVuUHJvZHVjZUNvbnN0cnVjdG9yVGhyb3dzKCkgXyU+CiAgICAgICAgfQogICAgICAgIDwlXyB9ICU+IDwlXyAtJT4KICAgIH0KCiAgICBwdWJsaWMgc3RydWN0IFZlcmlmeSB7CiAgICAgICAgZmlsZXByaXZhdGUgdmFyIG1ldGhvZDogTWV0aG9kVHlwZQoKICAgICAgICA8JV8gZm9yIG1ldGhvZCBpbiB3cmFwcGVkTWV0aG9kc0Zvck1ldGhvZFR5cGUgeyAtJT4KICAgICAgICA8JT0gbWV0aG9kLnZlcmlmaWNhdGlvblByb3h5Q29uc3RydWN0b3JOYW1lKCkgLSU+IHsgPCU9IG1ldGhvZC52ZXJpZmljYXRpb25Qcm94eUNvbnN0cnVjdG9yKCkgXyU+IH0KICAgICAgICA8JV8gfSAlPiA8JV8gLSU+CiAgICAgICAgPCVfIGZvciB2YXJpYWJsZSBpbiBhbGxWYXJpYWJsZXMgeyAtJT4KICAgICAgICA8JT0gcHJvcGVydHlUeXBlcyh2YXJpYWJsZSkgJT4KICAgICAgICA8JV8gfSAlPiA8JV8gLSU+CiAgICAgICAgPCVfIGZvciB3cmFwcGVkIGluIHdyYXBwZWRTdWJzY3JpcHRzIHsgLSU+CiAgICAgICAgPCU9IHdyYXBwZWQudmVyaWZ5Q29uc3RydWN0b3JOYW1lKCkgLSU+IHsgPCU9IHdyYXBwZWQudmVyaWZ5Q29uc3RydWN0b3IoKSBfJT4gfQogICAgICAgIDwlXyBpZiAhd3JhcHBlZC5yZWFkb25seSB7IC0lPgogICAgICAgIDwlPSB3cmFwcGVkLnZlcmlmeUNvbnN0cnVjdG9yTmFtZShzZXQ6IHRydWUpIC0lPiB7IDwlPSB3cmFwcGVkLnZlcmlmeUNvbnN0cnVjdG9yKHNldDogdHJ1ZSkgXyU+IH0KICAgICAgICA8JV8gfSAtJT4KICAgICAgICA8JV8gfSAlPiA8JV8gLSU+CiAgICB9CgogICAgcHVibGljIHN0cnVjdCBQZXJmb3JtIHsKICAgICAgICBmaWxlcHJpdmF0ZSB2YXIgbWV0aG9kOiBNZXRob2RUeXBlCiAgICAgICAgdmFyIHBlcmZvcm1zOiBBbnkKCiAgICAgICAgPCVfIGZvciBtZXRob2QgaW4gd3JhcHBlZE1ldGhvZHNGb3JNZXRob2RUeXBlIHsgLSU+CiAgICAgICAgPCU9IG1ldGhvZC5wZXJmb3JtUHJveHlDb25zdHJ1Y3Rvck5hbWUoKSAtJT4gewogICAgICAgICAgICA8JT0gbWV0aG9kLnBlcmZvcm1Qcm94eUNvbnN0cnVjdG9yKCkgXyU+CiAgICAgICAgfQogICAgICAgIDwlXyB9ICU+IDwlXyAtJT4KICAgIH0KCiAgPCUjID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IE1PQ0sgTUVUSE9EUyAtJT48JV8gLSU+CiAgICBwdWJsaWMgZnVuYyBnaXZlbihfIG1ldGhvZDogR2l2ZW4pIHsKICAgICAgICBtZXRob2RSZXR1cm5WYWx1ZXMuYXBwZW5kKG1ldGhvZCkKICAgIH0KCiAgICBwdWJsaWMgZnVuYyBwZXJmb3JtKF8gbWV0aG9kOiBQZXJmb3JtKSB7CiAgICAgICAgbWV0aG9kUGVyZm9ybVZhbHVlcy5hcHBlbmQobWV0aG9kKQogICAgICAgIG1ldGhvZFBlcmZvcm1WYWx1ZXMuc29ydCB7ICQwLm1ldGhvZC5pbnRWYWx1ZSgpIDwgJDEubWV0aG9kLmludFZhbHVlKCkgfQogICAgfQoKICAgIHB1YmxpYyBmdW5jIHZlcmlmeShfIG1ldGhvZDogVmVyaWZ5LCBjb3VudDogQ291bnQgPSBDb3VudC5tb3JlT3JFcXVhbCh0bzogMSksIGZpbGU6IFN0YXRpY1N0cmluZyA9ICNmaWxlLCBsaW5lOiBVSW50ID0gI2xpbmUpIHsKICAgICAgICBsZXQgZnVsbE1hdGNoZXMgPSBtYXRjaGluZ0NhbGxzKG1ldGhvZCwgZmlsZTogZmlsZSwgbGluZTogbGluZSkKICAgICAgICBsZXQgc3VjY2VzcyA9IGNvdW50Lm1hdGNoZXMoZnVsbE1hdGNoZXMpCiAgICAgICAgbGV0IGFzc2VydGlvbk5hbWUgPSBtZXRob2QubWV0aG9kLmFzc2VydGlvbk5hbWUoKQogICAgICAgIGxldCBmZWVkYmFjazogU3RyaW5nID0gewogICAgICAgICAgICBndWFyZCAhc3VjY2VzcyBlbHNlIHsgcmV0dXJuICIiIH0KICAgICAgICAgICAgcmV0dXJuIFV0aWxzLmNsb3Nlc3RDYWxsc01lc3NhZ2UoCiAgICAgICAgICAgICAgICBmb3I6IHNlbGYuaW52b2NhdGlvbnMubWFwIHsgaW52b2NhdGlvbiBpbgogICAgICAgICAgICAgICAgICAgIG1hdGNoZXIuc2V0KGZpbGU6IGZpbGUsIGxpbmU6IGxpbmUpCiAgICAgICAgICAgICAgICAgICAgZGVmZXIgeyBtYXRjaGVyLmNsZWFyRmlsZUFuZExpbmUoKSB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE1ldGhvZFR5cGUuY29tcGFyZVBhcmFtZXRlcnMobGhzOiBpbnZvY2F0aW9uLCByaHM6IG1ldGhvZC5tZXRob2QsIG1hdGNoZXI6IG1hdGNoZXIpCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgbmFtZTogYXNzZXJ0aW9uTmFtZQogICAgICAgICAgICApCiAgICAgICAgfSgpCiAgICAgICAgTW9ja3lBc3NlcnQoc3VjY2VzcywgIkV4cGVjdGVkOiBcKGNvdW50KSBpbnZvY2F0aW9ucyBvZiBgXChhc3NlcnRpb25OYW1lKWAsIGJ1dCB3YXM6IFwoZnVsbE1hdGNoZXMpLlwoZmVlZGJhY2spIiwgZmlsZTogZmlsZSwgbGluZTogbGluZSkKICAgIH0KCiAgICBwcml2YXRlIGZ1bmMgYWRkSW52b2NhdGlvbihfIGNhbGw6IE1ldGhvZFR5cGUpIHsKICAgICAgICBzZWxmLnF1ZXVlLnN5bmMgeyBpbnZvY2F0aW9ucy5hcHBlbmQoY2FsbCkgfQogICAgfQogICAgcHJpdmF0ZSBmdW5jIG1ldGhvZFJldHVyblZhbHVlKF8gbWV0aG9kOiBNZXRob2RUeXBlKSB0aHJvd3MgLT4gU3R1YlByb2R1Y3QgewogICAgICAgIG1hdGNoZXIuc2V0KGZpbGU6IHNlbGYuZmlsZSwgbGluZTogc2VsZi5saW5lKQogICAgICAgIGRlZmVyIHsgbWF0Y2hlci5jbGVhckZpbGVBbmRMaW5lKCkgfQogICAgICAgIGxldCBjYW5kaWRhdGVzID0gc2VxdWVuY2luZ1BvbGljeS5zb3J0ZWQobWV0aG9kUmV0dXJuVmFsdWVzLCBieTogeyAkMC5tZXRob2QuaW50VmFsdWUoKSA+ICQxLm1ldGhvZC5pbnRWYWx1ZSgpIH0pCiAgICAgICAgbGV0IG1hdGNoZWQgPSBjYW5kaWRhdGVzLmZpcnN0KHdoZXJlOiB7ICQwLmlzVmFsaWQgJiYgTWV0aG9kVHlwZS5jb21wYXJlUGFyYW1ldGVycyhsaHM6ICQwLm1ldGhvZCwgcmhzOiBtZXRob2QsIG1hdGNoZXI6IG1hdGNoZXIpLmlzRnVsbE1hdGNoIH0pCiAgICAgICAgZ3VhcmQgbGV0IHByb2R1Y3QgPSBtYXRjaGVkPy5nZXRQcm9kdWN0KHBvbGljeTogc2VsZi5zdHViYmluZ1BvbGljeSkgZWxzZSB7IHRocm93IE1vY2tFcnJvci5ub3RTdHViZWQgfQogICAgICAgIHJldHVybiBwcm9kdWN0CiAgICB9CiAgICBwcml2YXRlIGZ1bmMgbWV0aG9kUGVyZm9ybVZhbHVlKF8gbWV0aG9kOiBNZXRob2RUeXBlKSAtPiBBbnk/IHsKICAgICAgICBtYXRjaGVyLnNldChmaWxlOiBzZWxmLmZpbGUsIGxpbmU6IHNlbGYubGluZSkKICAgICAgICBkZWZlciB7IG1hdGNoZXIuY2xlYXJGaWxlQW5kTGluZSgpIH0KICAgICAgICBsZXQgbWF0Y2hlZCA9IG1ldGhvZFBlcmZvcm1WYWx1ZXMucmV2ZXJzZWQoKS5maXJzdCB7IE1ldGhvZFR5cGUuY29tcGFyZVBhcmFtZXRlcnMobGhzOiAkMC5tZXRob2QsIHJoczogbWV0aG9kLCBtYXRjaGVyOiBtYXRjaGVyKS5pc0Z1bGxNYXRjaCB9CiAgICAgICAgcmV0dXJuIG1hdGNoZWQ/LnBlcmZvcm1zCiAgICB9CiAgICBwcml2YXRlIGZ1bmMgbWF0Y2hpbmdDYWxscyhfIG1ldGhvZDogTWV0aG9kVHlwZSwgZmlsZTogU3RhdGljU3RyaW5nPywgbGluZTogVUludD8pIC0+IFtNZXRob2RUeXBlXSB7CiAgICAgICAgbWF0Y2hlci5zZXQoZmlsZTogZmlsZSA/PyBzZWxmLmZpbGUsIGxpbmU6IGxpbmUgPz8gc2VsZi5saW5lKQogICAgICAgIGRlZmVyIHsgbWF0Y2hlci5jbGVhckZpbGVBbmRMaW5lKCkgfQogICAgICAgIHJldHVybiBpbnZvY2F0aW9ucy5maWx0ZXIgeyBNZXRob2RUeXBlLmNvbXBhcmVQYXJhbWV0ZXJzKGxoczogJDAsIHJoczogbWV0aG9kLCBtYXRjaGVyOiBtYXRjaGVyKS5pc0Z1bGxNYXRjaCB9CiAgICB9CiAgICBwcml2YXRlIGZ1bmMgbWF0Y2hpbmdDYWxscyhfIG1ldGhvZDogVmVyaWZ5LCBmaWxlOiBTdGF0aWNTdHJpbmc/LCBsaW5lOiBVSW50PykgLT4gSW50IHsKICAgICAgICByZXR1cm4gbWF0Y2hpbmdDYWxscyhtZXRob2QubWV0aG9kLCBmaWxlOiBmaWxlLCBsaW5lOiBsaW5lKS5jb3VudAogICAgfQogICAgcHJpdmF0ZSBmdW5jIGdpdmVuR2V0dGVyVmFsdWU8VD4oXyBtZXRob2Q6IE1ldGhvZFR5cGUsIF8gbWVzc2FnZTogU3RyaW5nKSAtPiBUIHsKICAgICAgICBkbyB7CiAgICAgICAgICAgIHJldHVybiB0cnkgbWV0aG9kUmV0dXJuVmFsdWUobWV0aG9kKS5jYXN0ZWQoKQogICAgICAgIH0gY2F0Y2ggewogICAgICAgICAgICBvbkZhdGFsRmFpbHVyZShtZXNzYWdlKQogICAgICAgICAgICBGYWlsdXJlKG1lc3NhZ2UpCiAgICAgICAgfQogICAgfQogICAgcHJpdmF0ZSBmdW5jIG9wdGlvbmFsR2l2ZW5HZXR0ZXJWYWx1ZTxUPihfIG1ldGhvZDogTWV0aG9kVHlwZSwgXyBtZXNzYWdlOiBTdHJpbmcpIC0+IFQ/IHsKICAgICAgICBkbyB7CiAgICAgICAgICAgIHJldHVybiB0cnkgbWV0aG9kUmV0dXJuVmFsdWUobWV0aG9kKS5jYXN0ZWQoKQogICAgICAgIH0gY2F0Y2ggewogICAgICAgICAgICByZXR1cm4gbmlsCiAgICAgICAgfQogICAgfQogICAgcHJpdmF0ZSBmdW5jIG9uRmF0YWxGYWlsdXJlKF8gbWVzc2FnZTogU3RyaW5nKSB7CiAgICAgICAgZ3VhcmQgbGV0IGZpbGUgPSBzZWxmLmZpbGUsIGxldCBsaW5lID0gc2VsZi5saW5lIGVsc2UgeyByZXR1cm4gfSAvLyBMZXQgaWYgZmFpbCBpZiBjYW5ub3QgaGFuZGxlIGdyYXRlZnVsbHkKICAgICAgICBTd2lmdHlNb2NreVRlc3RPYnNlcnZlci5oYW5kbGVGYXRhbEVycm9yKG1lc3NhZ2U6IG1lc3NhZ2UsIGZpbGU6IGZpbGUsIGxpbmU6IGxpbmUpCiAgICB9CiAgPCUjID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IFNUQVRJQyBNT0NLIE1FVEhPRFMgLSU+PCVfIC0lPgogICAgPCVfIGlmIGNvbmZvcm1zVG9TdGF0aWNNb2NrIHsgLSU+CgogICAgc3RhdGljIHB1YmxpYyBmdW5jIGdpdmVuKF8gbWV0aG9kOiBTdGF0aWNHaXZlbikgewogICAgICAgIG1ldGhvZFJldHVyblZhbHVlcy5hcHBlbmQobWV0aG9kKQogICAgfQoKICAgIHN0YXRpYyBwdWJsaWMgZnVuYyBwZXJmb3JtKF8gbWV0aG9kOiBTdGF0aWNQZXJmb3JtKSB7CiAgICAgICAgbWV0aG9kUGVyZm9ybVZhbHVlcy5hcHBlbmQobWV0aG9kKQogICAgICAgIG1ldGhvZFBlcmZvcm1WYWx1ZXMuc29ydCB7ICQwLm1ldGhvZC5pbnRWYWx1ZSgpIDwgJDEubWV0aG9kLmludFZhbHVlKCkgfQogICAgfQoKICAgIHN0YXRpYyBwdWJsaWMgZnVuYyB2ZXJpZnkoXyBtZXRob2Q6IFN0YXRpY1ZlcmlmeSwgY291bnQ6IENvdW50ID0gQ291bnQubW9yZU9yRXF1YWwodG86IDEpLCBmaWxlOiBTdGF0aWNTdHJpbmcgPSAjZmlsZSwgbGluZTogVUludCA9ICNsaW5lKSB7CiAgICAgICAgbGV0IGZ1bGxNYXRjaGVzID0gbWF0Y2hpbmdDYWxscyhtZXRob2QsIGZpbGU6IGZpbGUsIGxpbmU6IGxpbmUpCiAgICAgICAgbGV0IHN1Y2Nlc3MgPSBjb3VudC5tYXRjaGVzKGZ1bGxNYXRjaGVzKQogICAgICAgIGxldCBhc3NlcnRpb25OYW1lID0gbWV0aG9kLm1ldGhvZC5hc3NlcnRpb25OYW1lKCkKICAgICAgICBsZXQgZmVlZGJhY2s6IFN0cmluZyA9IHsKICAgICAgICAgICAgZ3VhcmQgIXN1Y2Nlc3MgZWxzZSB7IHJldHVybiAiIiB9CiAgICAgICAgICAgIHJldHVybiBVdGlscy5jbG9zZXN0Q2FsbHNNZXNzYWdlKAogICAgICAgICAgICAgICAgZm9yOiBzZWxmLmludm9jYXRpb25zLm1hcCB7IGludm9jYXRpb24gaW4KICAgICAgICAgICAgICAgICAgICBtYXRjaGVyLnNldChmaWxlOiBmaWxlLCBsaW5lOiBsaW5lKQogICAgICAgICAgICAgICAgICAgIGRlZmVyIHsgbWF0Y2hlci5jbGVhckZpbGVBbmRMaW5lKCkgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiBTdGF0aWNNZXRob2RUeXBlLmNvbXBhcmVQYXJhbWV0ZXJzKGxoczogaW52b2NhdGlvbiwgcmhzOiBtZXRob2QubWV0aG9kLCBtYXRjaGVyOiBtYXRjaGVyKQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIG5hbWU6IGFzc2VydGlvbk5hbWUKICAgICAgICAgICAgKQogICAgICAgIH0oKQogICAgICAgIE1vY2t5QXNzZXJ0KHN1Y2Nlc3MsICJFeHBlY3RlZDogXChjb3VudCkgaW52b2NhdGlvbnMgb2YgYFwoYXNzZXJ0aW9uTmFtZSlgLCBidXQgd2FzOiBcKGZ1bGxNYXRjaGVzKS5cKGZlZWRiYWNrKSIsIGZpbGU6IGZpbGUsIGxpbmU6IGxpbmUpCiAgICB9CgogICAgc3RhdGljIHByaXZhdGUgZnVuYyBhZGRJbnZvY2F0aW9uKF8gY2FsbDogU3RhdGljTWV0aG9kVHlwZSkgewogICAgICAgIHNlbGYucXVldWUuc3luYyB7IGludm9jYXRpb25zLmFwcGVuZChjYWxsKSB9CiAgICB9CiAgICBzdGF0aWMgcHJpdmF0ZSBmdW5jIG1ldGhvZFJldHVyblZhbHVlKF8gbWV0aG9kOiBTdGF0aWNNZXRob2RUeXBlKSB0aHJvd3MgLT4gU3R1YlByb2R1Y3QgewogICAgICAgIGxldCBjYW5kaWRhdGVzID0gc2VxdWVuY2luZ1BvbGljeS5zb3J0ZWQobWV0aG9kUmV0dXJuVmFsdWVzLCBieTogeyAkMC5tZXRob2QuaW50VmFsdWUoKSA+ICQxLm1ldGhvZC5pbnRWYWx1ZSgpIH0pCiAgICAgICAgbGV0IG1hdGNoZWQgPSBjYW5kaWRhdGVzLmZpcnN0KHdoZXJlOiB7ICQwLmlzVmFsaWQgJiYgU3RhdGljTWV0aG9kVHlwZS5jb21wYXJlUGFyYW1ldGVycyhsaHM6ICQwLm1ldGhvZCwgcmhzOiBtZXRob2QsIG1hdGNoZXI6IG1hdGNoZXIpLmlzRnVsbE1hdGNoIH0pCiAgICAgICAgZ3VhcmQgbGV0IHByb2R1Y3QgPSBtYXRjaGVkPy5nZXRQcm9kdWN0KHBvbGljeTogc2VsZi5zdHViYmluZ1BvbGljeSkgZWxzZSB7IHRocm93IE1vY2tFcnJvci5ub3RTdHViZWQgfQogICAgICAgIHJldHVybiBwcm9kdWN0CiAgICB9CiAgICBzdGF0aWMgcHJpdmF0ZSBmdW5jIG1ldGhvZFBlcmZvcm1WYWx1ZShfIG1ldGhvZDogU3RhdGljTWV0aG9kVHlwZSkgLT4gQW55PyB7CiAgICAgICAgbGV0IG1hdGNoZWQgPSBtZXRob2RQZXJmb3JtVmFsdWVzLnJldmVyc2VkKCkuZmlyc3QgeyBTdGF0aWNNZXRob2RUeXBlLmNvbXBhcmVQYXJhbWV0ZXJzKGxoczogJDAubWV0aG9kLCByaHM6IG1ldGhvZCwgbWF0Y2hlcjogbWF0Y2hlcikuaXNGdWxsTWF0Y2ggfQogICAgICAgIHJldHVybiBtYXRjaGVkPy5wZXJmb3JtcwogICAgfQogICAgc3RhdGljIHByaXZhdGUgZnVuYyBtYXRjaGluZ0NhbGxzKF8gbWV0aG9kOiBTdGF0aWNNZXRob2RUeXBlLCBmaWxlOiBTdGF0aWNTdHJpbmc/LCBsaW5lOiBVSW50PykgLT4gW1N0YXRpY01ldGhvZFR5cGVdIHsKICAgICAgICBtYXRjaGVyLnNldChmaWxlOiBmaWxlLCBsaW5lOiBsaW5lKQogICAgICAgIGRlZmVyIHsgbWF0Y2hlci5jbGVhckZpbGVBbmRMaW5lKCkgfQogICAgICAgIHJldHVybiBpbnZvY2F0aW9ucy5maWx0ZXIgeyBTdGF0aWNNZXRob2RUeXBlLmNvbXBhcmVQYXJhbWV0ZXJzKGxoczogJDAsIHJoczogbWV0aG9kLCBtYXRjaGVyOiBtYXRjaGVyKS5pc0Z1bGxNYXRjaCB9CiAgICB9CiAgICBzdGF0aWMgcHJpdmF0ZSBmdW5jIG1hdGNoaW5nQ2FsbHMoXyBtZXRob2Q6IFN0YXRpY1ZlcmlmeSwgZmlsZTogU3RhdGljU3RyaW5nPywgbGluZTogVUludD8pIC0+IEludCB7CiAgICAgICAgcmV0dXJuIG1hdGNoaW5nQ2FsbHMobWV0aG9kLm1ldGhvZCwgZmlsZTogZmlsZSwgbGluZTogbGluZSkuY291bnQKICAgIH0KICAgIHN0YXRpYyBwcml2YXRlIGZ1bmMgZ2l2ZW5HZXR0ZXJWYWx1ZTxUPihfIG1ldGhvZDogU3RhdGljTWV0aG9kVHlwZSwgXyBtZXNzYWdlOiBTdHJpbmcpIC0+IFQgewogICAgICAgIGRvIHsKICAgICAgICAgICAgcmV0dXJuIHRyeSBtZXRob2RSZXR1cm5WYWx1ZShtZXRob2QpLmNhc3RlZCgpCiAgICAgICAgfSBjYXRjaCB7CiAgICAgICAgICAgIEZhaWx1cmUobWVzc2FnZSkKICAgICAgICB9CiAgICB9CiAgICBzdGF0aWMgcHJpdmF0ZSBmdW5jIG9wdGlvbmFsR2l2ZW5HZXR0ZXJWYWx1ZTxUPihfIG1ldGhvZDogU3RhdGljTWV0aG9kVHlwZSwgXyBtZXNzYWdlOiBTdHJpbmcpIC0+IFQ/IHsKICAgICAgICBkbyB7CiAgICAgICAgICAgIHJldHVybiB0cnkgbWV0aG9kUmV0dXJuVmFsdWUobWV0aG9kKS5jYXN0ZWQoKQogICAgICAgIH0gY2F0Y2ggewogICAgICAgICAgICByZXR1cm4gbmlsCiAgICAgICAgfQogICAgfQogICAgPCVfIH0gLSU+CjwlXyBpZiBhdXRvTW9ja2FibGUgeyAtJT4KfQoKPCVfIH0gZWxzZSB7IC0lPgovLyBzb3VyY2VyeTplbmQKPCVfIH0gLSU+CjwlIH0gLSU+CjwlXyBpZiBtb2NrZWRDb3VudCA9PSAwIHsgLSU+Ci8vIFN3aWZ0eU1vY2t5OiBubyBBdXRvTW9ja2FibGUgZm91bmQuCi8vIFBsZWFzZSBkZWZpbmUgYW5kIGluaGVyaXQgZnJvbSBBdXRvTW9ja2FibGUsIG9yIGFubm90YXRlIHByb3RvY29scyB0byBiZSBtb2NrZWQKPCVfIH0gLSU+Cg=="
    )
}
